Spring企业级程序设计 • 【第2章 Spring Bean管理进阶】
全部章节 >>>>
本章目录
2.3.5 @PostConstruct和@PreDestory注解
2.1 bean标签和import标签
<bean>标签是用来定义一个Bean对象的。
<bean>标签的属性有很多,其中常用属性有:id、name、class、factory-method、factory-bean、init-method、destory-method、scope和autowire属性,而class、factory-method和factory-bean属性在前面的章节中已经接触过,这里不再详解。
2.1.1 <bean>标签中的id属性和name属性
id属性是Bean的唯一标识,IoC容器中<bean>标签的id属性不能重复,否则会报错。在Spring4.x之前的版本id的属性值不能包含特殊字符且必须是字母或者下划线开头,在本案例中,将验证id属性的唯一性。
示例:IoC容器中<bean>标签的id属性不能重复,否则会报错
在com.mhys.pojo包下创建一个Student类,添加name属性
public class Student {
private String name;
// set()方法和get()方法省略
}
在applicationContext.xml文件中注入Student类,两个<bean>标签的id属性值一样
<!-- 创建两个id属性名一样的Bean -->
<bean id="student" class="com.mhys.pojo.Student"></bean>
<bean id="student" class="com.mhys.pojo.Student"></bean>
在com.mhys.test包下,编写测试类,在控制台输出结果。 运行程序,在控制台中,查看输出结果
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Student stu = (Student) context.getBean("student");
System.out.println(stu);
}
}
name属性是Bean的名称标识,IoC容器中<bean>标签的name属性可以重复,name属性的属性值可以包含特殊字符,在Spring4.x之后的版本name的属性值必须唯一。
示例:通过name属性定义Bean
在com.mhys.pojo包下创建一个Dog类
public class Dog {
public void cry(){
System.out.println("我是一条小狗,汪、汪、汪!");
}
}
在applicationContext.xml文件中注册Dog类到容器
<!-- 通过name属性定义bean,属性值带有特殊字符 -->
<bean name="%@#dto%#" class="com.mhys.pojo.Dog"></bean>
在com.mhys.test包下,编写测试类,在控制台输出结果。 运行程序,在控制台中,查看输出结果
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Dog dog = (Dog) context.getBean("%@#dto%#");
dog.cry();
}
}
2.1.2 Bean的作用范围和生命周期
scope属性:Bean的作用范围是通过scope属性来控制的,常用取值有四种:
- singleton:单例对象,被标识为单例的对象在Spring容器中只会存在一个实体。
- prototype:多例原型,被标识为多例的对象,每次需要获取对象是才会创建,每次创建都是新的对象。
- request:Web环境下,对象与Request生命周期一致。
- session:Web环境下,对象与Session生命周期一致。
示例:通过scope属性来了解Bean的作用范围
在com.mhys.pojo包下创建一个Cat类
public class Cat {
private String name;
private String color;
// set()方法和get()方法省略
}
在applicationContext.xml文件中注册Cat类到容器
<bean name="cat" class="com.mhys.pojo.Cat"></bean>
在com.mhys.test包下,编写测试类,在控制台输出结果。
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Cat cat1 = (Cat) context.getBean("cat");
Cat cat2 = (Cat) context.getBean("cat");
if(cat1==cat2){
System.out.println("cat1与cat2是同一个对象!");
}else{
System.out.println("cat1与cat2不是同一个对象!");
}
}
}
运行程序,在控制台出结果
在applicationContext.xml文件中修改Cat类的bean标签,scope属性值为prototype
<bean name="cat" class="com.mhys.pojo.Cat" scope="prototype"></bean>
运行程序,在控制台中查看输出结果
2.1.2 Bean的生命周期
Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean。
init-method属性用于在Bean初始化时指定初始化方法
destroy-method用于在Bean销毁时指定的调用的方法
示例:使用init-method属性和destroy-method属性来指定初始化和销毁方法,最后在控制台输出结果。
在Cat类中声明init()方法和destroy()方法
public class Cat {
private String name;
private String color;
// set()方法和get()方法省略
public void init(){
System.out.println("初始化方法被执行");
}
public void destory(){
System.out.println("销毁方法被执行");
}
}
在applicationContext.xml配置文件中修改name属性为cat的<bean>标签
<bean name="cat" class="com.mhys.pojo.Cat" init-method="init" destroy-method="destory"></bean>
在com.mhys.test包下,编写测试类,在控制台输出结果。
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Cat cat = (Cat) context.getBean("cat"); // 此时会执行init()方法
context.close(); // 容器关闭,此时会执行destrory()方法
}
}
运行程序,在控制台出结果
2.1.3 <import>标签实现分模块配置
在企业项目开发中,配置文件中的信息非常多,经常会分模块开发,Spring提供<import>标签实现分模块配置,将多个模块的配置文件分开进行配置,最后再整合。
示例:定义三个模块,用户模块、角色模块和订单模块来模拟企业中的分模块开发
- 创建com.mhys.user包,存放用户模块的相关代码,在包中创建User类
- 在com.mhys.user包中创建applicationContext-user.xml配置文件,注入User类
- 创建com.mhys.role包,存放角色模块的相关代码,在包中创建Role类。
- 在com.mhys.role包中创建applicationContext-role.xml配置文件,注入Role类
示例:定义三个模块,用户模块、角色模块和订单模块来模拟企业中的分模块开发
- 创建com.mhys.order包,存放订单模块的相关代码,在包中创建Order类
- 在com.mhys.order包中创建applicationContext-order.xml配置文件,注入Order类
- 在src目录下创建applicationContext.xml配置文件,引入3个模块的配置文件
- 在com.mhys.test包下编写测试类,在控制台输出结果
- 运行程序,在控制台中查看输出结果
2.1.4 实践练习
2.2 复杂类型注入
在Spring框架中,属性的注入有多种方式,可以通过构造方法注入、set方法注入、和p命名空间注入等方式,而对于复杂的数据类型比如数组、List集合、Map集合和Properties等,Spring也提供了相应的注入方式。
2.2.1 数组元素注入
示例:使用<list>标签注入数组元素
在com.mhys.pojo包下创建User类,添加names属性。
public class User {
private String[] names;
// set()方法和get()方法省略
}
在applicationContext.xml配置文件中注册User类到容器。
<bean id="user" class="com.mhys.pojo.User">
<property name="names">
<list>
<value>张XX</value>
<value>小XX</value>
<value>LuXX</value>
</list>
</property>
</bean>
在com.mhys.test包下创建测试类。
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
String[] names = user.getNames();
for(String name : names){
System.out.println(name);
}
}
}
在控制台中,查看输出结果
2.2.2 List集合注入
示例:在applicationContext.xml配置文件中,注入List集合
在User类中增加List集合类型属性。
public class User {
private String[] names;
private List<String> hobbys;
// set()方法和get()方法省略
}
在applicationContext.xml配置文件中注入List集合属性。
<bean id="user" class="com.mhys.pojo.User">
<property name="hobbys">
// 省略原有代码
<list>
<value>跑步</value>
<value>看书</value>
<value>骑单车</value>
<value>打羽毛球</value>
</list>
</property>
</bean>
在com.mhys.test包下创建测试类。 在控制台中,查看输出结果
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
List<String> hobbys = user.getHobbys();
for(String hobby : hobbys){
System.out.println(hobby);
}
}
}
2.2.3 Map集合注入
示例:在applicationContext.xml配置文件中注入Map集合属性
在com.mhys.pojo包下创建DataSource类,添加Map集合类型属性。
public class DataSource {
private Map<String, String> map;
// set()方法和get()方法省略
}
在applicationContext.xml配置文件中注册DataSource类到容器并注入Map集合属性。
<bean id="dataSource" class="com.mhys.pojo.DataSource">
<property name="map">
<map>
<entry key="driverClassName" value="com.mysql.jdbc.Driver"></entry>
<entry key="url" value="jdbc:mysql://localhost:3306/mysql"></entry>
<entry key="username" value="root"></entry>
<entry key="password" value="rootroot"></entry>
</map>
</property>
</bean>
在com.mhys.test包下创建测试类。 在控制台中,查看输出结果
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) context.getBean("dataSource");
Map<String, String> map = dataSource.getMap();
System.out.println(map.get("username"));
System.out.println(map.get("password"));
System.out.println(map.get("url"));
System.out.println(map.get("driverClassName"));
}
}
2.2.4 Properties集合注入
示例:在applicationContext.xml配置文件中注入Properties类型数据
在DataSource类中增加properties属性。
public class DataSource {
private Map<String, String> map;
private Properties properties;
// set()方法和get()方法省略
}
在applicationContext.xml配置文件中注入Properties类型属性。
<bean id="dataSource" class="com.mhys.pojo.DataSource">
// 省略原有代码
<property name="properties">
<props>
<prop key="driverClassName">oracle.jdbc.driver.OracleDriver</prop>
<prop key="url">jdbc:oracle:thin:@localhost::1521:myoracle</prop>
<prop key="username">scott</prop>
<prop key="password">1q2w3e</prop>
</props>
</property>
</bean>
在com.mhys.test包下创建测试类。 在控制台中,查看输出结果
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) context.getBean("dataSource");
Properties pro = dataSource.getProperties();
System.out.println(pro.get("username"));
System.out.println(pro.get("password"));
System.out.println(pro.get("url"));
System.out.println(pro.get("driverClassName"));
}
}
2.2.5 实践练习
2.3 通过注解方式配置Bean
传统的Spring是使用XML配置文件来对Bean进行注入、配置AOP以及配置声明式事务,这么做有两个缺点:
- 如果所有的内容都配置在XML文件中,那么XML文件将会十分庞大。如果按模块分开XML配置文件,那么XML配置文件又会非常多。总之这将导致配置文件的可读性与可维护性变得很低。
- 开发过程中,在.java文件和.xml文件之间不断切换,是一件麻烦的事,同时这种思维上的不连贯也会降低开发的效率。
为了解决使用XML配置文件来对Bean进行注入所带来的问题,Spring引入了注解,通过“@xxx”的方式让注解与Java Bean紧密结合,这样大大减少了配置文件的体积,又增加了Java Bean的可读性与内聚性。
2.3.1 @Component将对象注册到容器
@Component注解的使用方法
引入注解开发相关jar包。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd ">
<!—此处输入内容 -->
</beans>
在applicationContext.xml配置文件中引入context约束。
在applicationContext.xml配置文件中开启使用注解配置
<!-- 开启注解扫描功能扫描com.mhys.pojo包以及子包中的类-->
<context:component-scan base-package="com.mhys.pojo"></context:component-scan>
在com.mhys.pojo包下创建Tiger类,添加tigerType和tigerName两个属性,并使用@Component将Tiger类注册到容器
@Component
public class Tiger {
private String tigerType;
private String tigerName;
@Override
public String toString() {
return "Tiger [tigerType=" + tigerType + ", tigerName=" + tigerName + "]";
}
}
在com.mhys.test包下编写测试类 在控制台中查看输出结果
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Tiger tiger = (Tiger) context.getBean("tiger");
System.out.println(tiger);
}
}
2.3.2 @Value值类型注
使用@Value注解为Tiger类的两个属性注入属性值
在Tiger类中使用@Value注解注入属性值。
@Component
public class Tiger {
@Value("东北虎")
private String tigerType;
@Value("小白")
private String tigerName;
@Override
public String toString() {
return "Tiger [tigerType=" + tigerType + ", tigerName=" + tigerName + "]";
}
}
运行测试类程序,在控制台中查看输出结果。
2.3.3 @Autowired引用类型注入
创建Zoo类,添加Tiger类型属性,并通过注解注入到容器中,然后使用@Autowired引入Tiger类型属性值。
在com.mhys.pojo包下创建Zoo类,注册到容器中,添加Tiger类型属性,使用@AutoWired引入属性值。
@Component
public class Zoo {
@Autowired
private Tiger tiger;
@Override
public String toString() {
return "Zoo [tiger=" + tiger + "]";
}
}
编写测试类,并在控制台中,查看输出结果。
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Zoo zoo = (Zoo) context.getBean("zoo");
System.out.println(zoo);
}
}
2.3.4 @Scope设置对象作用范围
首先创建User类,添加username属性和password属性;然后使用@Scope指定注入到容器中Bean的作用范围;接着加载两个User对象,比较两个User对象是否相同;最后在控制台打印输出结果。。
在com.mhys.pojo包下创建User类,使用注解注册到容器并使用@Scope指定为单例,添加username和password两个属性。
@Component
@Scope("singleton")
public class User {
@Value("章XX)
private String username;
@Value("123qwe")
private String password;
}
编写测试类,并在控制台中,查看输出结果。
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user1 = (User) context.getBean("user");
User user2 = (User) context.getBean("user");
if(user1 == user2){
System.out.println("user1与user2是同一个对象!");
}else{
System.out.println("user1与user2不是同一个对象!");
}
}
}
在User类使用@Scope指定为多例。
@Component
@Scope("prototype")
public class User {
// 原有代码省略
}
运行程序,在控制台中查看输出结果。
2.3.5 @PostConstruct和@PreDestory注解
示例:在User类中声明init()方法和destory()方法,然后在方法上添加注解,最后在控制台打印输出结果。
在User类中使用注解注册到容器并使用@Scope指定为单例,添加username和password两个属性。
@Component
@Scope("singleton")
public class User {
// 原有代码省略
@PostConstruct
public void init(){
System.out.println("初始化方法被调用!");
}
@PreDestroy
public void detroy(){
System.out.println("销毁方法被调用!");
}
}
编写测试类,并在控制台中,查看输出结果。
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
}
}
在测试类中关闭容器。
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
context.close();
}
}
运行程序,在控制台中查看输出结果。
2.3.6 实践练习
2.4 综合案例
2.4.1 需求说明
图书查询系统,能够充分发挥信息化管理的方便性和快捷性,并能够与图书管理系统中的其他模块无缝结合,让图书馆管理人员便捷地工作。综合之前学过的知识,开发一个简易的图书查询系统。要求如下:
- 查询全部图书。
- 根据书籍编号查询信息。
- 根据书名查询书籍信息。
- 根据状态查询书籍信息。
总结
- Spring容器中的Bean可以分为5个范围:singleton、prototype 、 request 、 session 、 global-session
- Spring的单例Bean是线程安全的
- 如果Bean有多种状态的话,就需要自行保证线程安全。最浅显的解决办法就是将多态Bean的作用域由“singleton”变更为“prototype”。
- 相对于XML文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声明。开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用XML表述Bean的装配关系。
Spring企业级程序设计 • 【第2章 Spring Bean管理进阶】的更多相关文章
- Spring企业级程序设计作业目录(作业笔记)
Spring企业级程序设计 • [目录] 第1章 Spring之旅 >>> 1.1.6 使用Eclipse搭建的Spring开发环境,使用set注入方式为Bean对象注入属性值并打 ...
- Spring企业级程序设计 • 【目录】
章节 内容 实践练习 Spring企业级程序设计目录(作业笔记) 第1章 Spring企业级程序设计 • [第1章 Spring之旅] 第2章 Spring企业级程序设计 • [第2章 Spring ...
- Spring企业级程序设计 • 【第7章 Spring框架整合】
全部章节 >>>> 本章目录 7.1 模型数据解析及控制器返回值 7.1.1 SSM框架环境搭建 7.1.1 ModelAndView多种用法 7.1.2 整合MyBati ...
- Spring企业级程序设计 • 【第5章 Spring MVC快速入门】
全部章节 >>>> 本章目录 5.1 Spring MVC设计概述及其框架结构 5.1.1 Spring MVC介绍 5.1.1 Spring MVC优势 5.1.2 S ...
- Spring企业级程序设计 • 【第1章 Spring之旅】
全部章节 >>>> 本章目录 1.1 Spring框架基础 1.1.1 Spring特点及体系结构 1.1.1 Spring的体系结构 1.1.2 使用Eclipse搭建 ...
- Spring入门篇——第4章 Spring Bean装配(下)
第4章 Spring Bean装配(下) 介绍Bean的注解实现,Autowired注解说明,基于java的容器注解说明,以及Spring对JSR支持的说明 4-1 Spring Bean装配之Bea ...
- Spring入门篇——第3章 Spring Bean装配(上)
第3章 Spring Bean装配(上) 介绍Bean的作用域.生命周期.Aware接口.自动装配和Resource等内容. 3-1 Spring Bean装配之Bean的配置项及作用域 从上至下依次 ...
- Spring入门篇——第6章 Spring AOP的API介绍
第6章 Spring AOP的API介绍 主要介绍Spring AOP中常用的API. 6-1 Spring AOP API的Pointcut.advice概念及应用 映射方法是sa开头的所有方法 如 ...
- Spring入门篇——第5章 Spring AOP基本概念
第5章 Spring AOP基本概念 本章介绍Spring中AOP的基本概念和应用. 5-1 AOP基本概念及特点 5-2 配置切面aspect ref:引用另外一个Bean 5-3 配置切入点Poi ...
随机推荐
- 在 Qualys SSL Labs SSL 测试中获得 A+ 评级的秘技 2021 版
本系列文章将阐述主流应用交付控制器和主流 Web 服务器如何运行 HTTP/2 和 TLSv1.3 协议,以及如何在 SSL Test 中获得 A+ 评级. 请访问原文链接:https://sysin ...
- linux之sar命令详解
sar(System Activity Reporter系统活动情况报告)是目前Linux上最为全面的系统性能分析工具之一,可以从多个方面对系统的活动进行报告,包括:文件的读写情况.系统调用的使用情况 ...
- Linux学习 - 文本编辑器Vim
一.Vim工作模式 二.命令 插入 a 光标后插入 A 光标所在行尾插入 i 光标前插入 I 光标所在行首插入 o 光标下插入新行 O 光标上插入新行 删除 x 删除光标处字符 nx 删除光标处后 ...
- String直接赋值与使用new String的区别
在研究String直接赋值与new String的区别之前我们需要先了解java中的字符串常量池的概念 字符串常量池 String类是我们平常项目中使用频率非常高的一种对象类型,jvm为了提升性能和减 ...
- Java学习1:图解Java内存分析详解(实例)
首先需要明白以下几点: 栈空间(stack),连续的存储空间,遵循后进先出的原则,用于存放局部变量. 堆空间(heap),不连续的空间,用于存放new出的对象,或者说是类的实例. 方法区(method ...
- 【JavaWeb】【JSP】JSP传值到Servlet后端为NULL的问题
JSP传值到Servlet后端为NULL的问题 哔哩哔哩@萌狼蓝天 博客:萌狼工作室-博客园 联系QQ:#3447902411# | 仅限技术交流可添加 | 添加请说明你的方向和来意 1.目标文件路径 ...
- 快速上手ANTLR
回顾前文: ANTLR 简单介绍 ANTLR 相关术语 ANTLR 环境准备 下面通过两个实例来快速上手ANTLR. 使用Listener转换数组 完整源码见:https://github.com/b ...
- Snort 入侵检测系统
Snort 入侵检测系统 一.实验目的 1.掌握snort IDS工作原理 2.应用snort 三种方式工作 二.实验环境 系统环境:Windows环境, kali环境 三.实验原理 1.snort ...
- DevOps和SRE的区别
目录 一.误区 二.DevOps 和 SRE 定义 三.两者产生背景和历史 四.两者的职能不同 五.工作内容不同 六.DevOps 和 SRE 关系 七.附录:技能点 DevOps SRE 一.误区 ...
- 攻击科普:DDos
目录 一.DDoS 攻击究竟是什么? 二.DDoS 攻击多少G是什么意思? 二.DDoS攻击种类 ICMP Flood UDP Flood NTP Flood SYN Flood CC攻击 DNS Q ...