Bean的装配方式
手动显式装配
手动装配就是我们通过properties标签对Bean的属性进行显式配置
测试:
一、定义实体类
1、Dog
public class Dog {
public void shout(){
System.out.println("wang");
}
}
2、Cat
public class Cat {
public void shout(){
System.out.println("miao");
}
}
3、Person
@Data
@AllArgsConstructor
@NoArgsConstructor
public class People {
private String name;
private Dog dog;
private Cat cat;
}
二、配置文件注册Bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.guohui.pojo.Dog"/>
<bean id="cat" class="com.guohui.pojo.Cat"/>
<bean id="people" class="com.guohui.pojo.People">
<property name="name" value="张三"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
</bean>
</beans>
三、测试
public class MyTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
People people = context.getBean("people", People.class);
people.getCat().shout();
people.getDog().shout();
}
}
四、控制台
隐式的自动装配Autowired
曾经我们会将Bean中的所有属性都通过<properties/>标签进行装配注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.guohui.pojo.Dog"/>
<bean id="cat" class="com.guohui.pojo.Cat"/>
<bean id="people" class="com.guohui.pojo.People">
<property name="name" value="张三"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
</bean>
</beans>
现在出现了两种隐式装配注入的方式,运用AutoWired关键字
一、ByName注入
代码:
<bean id="dog" class="com.guohui.pojo.Dog"/>
<bean id="cat" class="com.guohui.pojo.Cat"/>
<bean id="people" class="com.guohui.pojo.People" autowire="byName">
<property name="name" value="张三"/>
</bean>
测试:
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
People people = context.getBean("people", People.class);
people.getCat().shout();
people.getDog().shout();
}
控制台:
二、ByType
代码:
<bean id="dog" class="com.guohui.pojo.Dog"/>
<bean id="cat" class="com.guohui.pojo.Cat"/>
<bean id="people" class="com.guohui.pojo.People" autowire="byType">
<property name="name" value="张三"/>
</bean>
测试:
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
People people = context.getBean("people", People.class);
people.getCat().shout();
people.getDog().shout();
}
控制台:
注意点:
1、ByName必须保证Bean中的属性字段名唯一,并且如果一个Bean中有某个Bean的属性,我们进行ByName装配的时候必须保证applicationContext.xml中这个Bean注册的id和Bean中set方法的参数一致
2、ByType必须保证所有Bean的Class唯一,并且在该Bean中的类型要全部不同!
注解实现自动装配@Autowired
一、使用注解自动装配的前提准备工作
1、导入约束
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd"
2、配置applicationContext.xml支持注解
<context:annotation-config/>
3、整体的导入情况
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
二、注解的使用
1、@Autowired
这个注解可以直接在Bean的属性上使用,自动装配先通过类型,再去找name,当然也可以加到对应属性的set方法,但是一般都加在属性上
注意:使用这个注解,如果将它加到Bean属性上,那么它对应的set方法也可以省略
(1)Bean中
public class People {
private String name;
@Autowired
private Dog dog;
@Autowired
private Cat cat;
(2)applicationContext.xml中十分干净,仅仅剩下注册Bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解的支持-->
<context:annotation-config/>
<bean id="dog" class="com.guohui.pojo.Dog"/>
<bean id="cat" class="com.guohui.pojo.Cat"/>
<bean id="people" class="com.guohui.pojo.People" autowire="byType">
</bean>
</beans>
(3)测试以及控制台结果
public class MyTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
People people = context.getBean("people", People.class);
people.getCat().shout();
people.getDog().shout();
}
}
(4)拓展:@Autowired注解有个参数,叫做required,如果我们在注解上显式的定义该属性的required = false,表示该属性为null,也不会报空指针异常
public @interface Autowired {
boolean required() default true;
}
使用方法:
@Autowired(required = false)
private Dog dog;
(5)和@Autowired常组合用的注解@Qualifier
当存在多个类型相同或者情况比较复杂的自动装配环境,这个时候使用@Qualifier注解就可以指定某个Bean的id,实现定位唯一的Bean对象进行注入
<bean id="dog1" class="com.guohui.pojo.Dog"/>
<bean id="dog2" class="com.guohui.pojo.Dog"/>
<bean id="cat1" class="com.guohui.pojo.Cat"/>
<bean id="cat2" class="com.guohui.pojo.Cat"/>
<bean id="people" class="com.guohui.pojo.People" autowire="byName">
使用方法:
注意:@Qualifier注解只有一个参数value,可以将value省略
public class People {
private String name;
@Autowired(required = false)
@Qualifier("dog1")
private Dog dog;
@Autowired
@Qualifier("cat1")
private Cat cat;
Bean的生命周期
Bean的生命周期,就是Bean从创建到销毁,所经历的各种方法的调用。简单来说,一个Bean的生命周期分为下面四个阶段:
实例化、属性设置、初始化、销毁
一、四个阶段的学习
1、实例化
程序启动后,Spring把注解或者配置文件定义好的Bean对象转换成一个BeanDefination对象,然后完成整个BeanDefination的解析和架子啊过程。Spring获取到这些完整的对象之后,会对整个BeanDefination进行实例化操作,实例化是通过反射的方式创建对象的
2、属性设置
实例化后的对象被封装在BeanWrapper对象中,并且此时的对象仍然是一个原生的状态,并没有进行依赖注入。Spring根据BeanDefination中的信息进行依赖注入,populateBean方法完成属性的注入
3、初始化
(1)调用Aware接口相关的方法:invokeAwareMethod(完成beanName、beanClassLoader、beanFactory对象的属性设置)
(2)调用beanPostprocessor中的前置处理方法(applyBeanPostProcessorsBeforeInitialization)
(3)调用InitMethod方法:invokeInitMethod(),判断是否实现了initializingBean接口,如果有,调用afterPropertiesSet方法,没有就不调用
(4)调用BeanPostProcessor后置处理方法(applyBeanPostProcessorsAfterInitialization),Spring的Aop就是在此处实现的
4、销毁
判断是否实现了DisposableBean接口,调用destoryMethod方法
至此,关于Bean的各种装配方式和Bean的生命周期,你已经全部掌握,欢迎点赞加收藏,后续依旧会持续的更新关于Spring的技术点,预祝各位早日成为全栈工程师!