3spring:生命周期,属性赋值,自动装配
有不懂的可以参考之前的文章!
https://www.cnblogs.com/Mrchengs/p/10109053.html
1.Bean的生命周期
创建---初始化---销毁
容器管理bean的生命周期:
我们可以自定义初始化和销毁的方法
构造器:
1.单实例:在容器创建好之后创建实例
2.多实例:在每次获取的时候创建对象
初始化:
对象创建好,并赋值好,进行初始化
销毁:
单实例:容器关闭的时候
多实例:容器不会管理这个bean,在容器关闭的时候不会调用销毁的方法
1.指定初始化和销毁的方法:通过@Bean的注解
相当于:init-method,destroy-method
public class Chirld { public Chirld() { System.out.println("创建Child实例...."); } public void init(){ System.out.println("初始化方法....."); } public void destroy(){ System.out.println("销毁方法...."); } }
@Configuration public class TheLifeOfInitAnfDestroy { @Bean(initMethod="init",destroyMethod="destroy") public Chirld car(){ return new Chirld(); } }
@Test public void test4(){ AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(TheLifeOfInitAnfDestroy.class); System.out.println("容器创建完成"); //关闭 app.close(); }
创建Child实例.... 初始化方法..... 容器创建完成 十一月 16, 2018 12:19:32 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@512ddf17: startup date [Fri Nov 16 00:19:32 CST 2018]; root of context hierarchy 销毁方法....
在容器关闭的时候进行销毁
2.接口方法
通过Bean实现InitializingBean自定义初始化逻辑
DisposableBean自定义销毁容器
public interface InitializingBean { void afterPropertiesSet() throws Exception; }
public interface DisposableBean { void destroy() throws Exception; }
@Component public class Chirld2 implements InitializingBean,DisposableBean { public Chirld2() { System.out.println("创建Child2实例...."); } public void afterPropertiesSet() throws Exception { System.out.println("init....."); } public void destroy() throws Exception { System.out.println("destroy...."); } }
@Configuration @ComponentScan("coom.MrChengs.bean") public class TheLifeOfInitAnfDestroy { }
@Test public void test4(){ AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(TheLifeOfInitAnfDestroy.class); System.out.println("容器创建完成"); //关闭 app.close(); }
创建Child2实例.... init..... 容器创建完成 十一月 16, 2018 12:35:43 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@512ddf17:
startup date [Fri Nov 16 00:35:43 CST 2018]; root of context hierarchy destroy....
3.可以使用JSR250
@PostConStruct:在bean创建完成并且属性赋值完成,来执行初始化
@PreDestroy:在容器销毁bean之前通知我们进行清理
//代码.....
4.BeanPostProcessor接口:bean的后置处理器
在bean初始化之后进行一些处理工作
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization: 在初始化之后工作
@Component
public class MyBeanPostProcessor implements BeanPostProcessor{
//bean:刚刚创建的实例
//beanName:bean的名字
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("post init.....");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("aftet init ....");
return bean;
}
}
@Configuration @ComponentScan("coom.MrChengs.bean") public class TheLifeOfInitAnfDestroy { }
@Test public void test4(){ AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(TheLifeOfInitAnfDestroy.class); System.out.println("容器创建完成"); //关闭 app.close(); }
post init..... aftet init .... post init..... aftet init .... post init..... aftet init .... 创建Child2实例.... post init..... init..... aftet init .... 容器创建完成 十一月 16, 2018 8:25:25 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@512ddf17: startup date [Fri Nov 16 08:25:24 CST 2018]; root of context hierarchy destroy....
底层对BeanPostProcessor的使用:
bean赋值,注入其他组建,@Autowire,生命周期注解功能。。。。。
2.属性赋值:
@Value("")
1.基本数值
2.可以写Spel : #{}
3.可以写 ${ } ,取出配置文件中的只
person.properties
person.school=MrChengs
public class Person { @Value("MrChengs") private String name; @Value("#{20-12}") private int age; @Value("${person.school}") private String school; ... }
@Configuration
//引入资源 @PropertySource(value={"classpath:/person.properties"}) public class ValueConfig { @Bean public Person person(){ return new Person(); } }
@Test public void test5(){ AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(ValueConfig.class); String [] names = app.getBeanDefinitionNames(); for(String name : names){ System.out.println(name); } Person person = app.getBean(Person.class); System.out.println(person); }
valueConfig person Person [name=MrChengs, age=8, school=MrChengs]
@PropertySource(value={"classpath:/person.properties"})用于加载配置文件
public @interface PropertySource { String name() default ""; String[] value(); boolean ignoreResourceNotFound() default false; String encoding() default ""; Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class; }
自动装配:
利用依赖注入(DI)完成对IOC容器中各个组件的依赖关系。
前提自动注入的需要提前在容器中
@Autowired
1.默认优先按照类型进行容器组件中查找
2.当容器中有多个相同类型的组件,再将属性的名作为组件的id去容器中查找
applicationContext.getBean("customerDao")... @Autowired private CustomerDao customerDao; 默认按照方法名去id中查找
3. @Qualifier
指定需要装配的组件id
@Qualifier("customerDao") @Autowired private CustomerDao customerDao2;
4.默认一定将属性赋值好
5.如果没有的情况下组件默认是null
不是必须的,此时容器中没有所需要装配的bean也不会报错
@Qualifier("customerDao") @Autowired(required=false) private CustomerDao customerDao2;
6.@Primary:让spring进行装配的时候,默认使用首选的bean
@Autowired(required=false) private CustomerDao customerDao; @Primary @Bean("customerDao2") public CustomerDao customer(){ ... }
@Repository public class CustomerDao { }
@Service public class CustomerService { @Autowired private CustomerDao customerDao; public void print(){ System.out.println("---->"+customerDao); } }
@Configuration @ComponentScan({"coom.MrChengs.config.service","coom.MrChengs.config.dao"}) public class AutowiredConfig { @Bean("customerDao2") public CustomerDao customer(){ return new CustomerDao("customer2"); } }
@Test public void test6(){ AnnotationConfigApplicationContext app = new
AnnotationConfigApplicationContext(coom.MrChengs.config.AutowiredConfig.class); String [] names = app.getBeanDefinitionNames(); for(String name : names){ System.out.println(name); } CustomerService cus = app.getBean(CustomerService.class); cus.print(); //System.out.println(cus); }
autowiredConfig customerService 此时容器中有两个相同类型的bean customerDao customerDao2 此时注入的类型是: ---->CustomerDao [name=null]
spring还支持@Resource和@Inject java规范注解
@Resource
可以实现和@Autowire一样的功能 实现,默认是按照组件的名称进行装配
@Resource private CustomerDao customerDao;
可以修改器默认装配的名称
@Resource(name="customerDao2") private CustomerDao customerDao;
不可以支持@Primary功能和request=false的功能
@Inject
需要导入下面的依赖
<!-- https://mvnrepository.com/artifact/javax.inject/javax.inject --> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>
@Inject private CustomerDao customerDao;
其实先功能和@Autowire功能一样
其本身没有属性,没有require=false这个属性
支持@Primary
@Autowire
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD,
ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired {
可以标注的位置有构造器,方法,属性
方法上
@Component public class Person { ... }
@Component public class Students { ... @Autowired public void setPerson(Person person) { this.person = person; } .. }
AnnotationConfigApplicationContext app = new
AnnotationConfigApplicationContext(coom.MrChengs.config.AutowiredConfig.class); Students s = app.getBean(Students.class); System.out.println(s); Person p = app.getBean(Person.class); System.out.println(p);
Students [person=Person [name=MrChengs, age=8, school=${person.school}], name=null] Person [name=MrChengs, age=8, school=${person.school}]
构造器:
@Autowired public Students(Person person, String name) { super(); this.person = person; this.name = name; System.out.println("Students....."); }
1.标注在方法位置上,@Bean+方法参数,参数从容器中获取
2.标注在构造器上:如果组件只有一个构造函数,可以省略
3.放在参数位置