【Spring】Spring常用注解(中)

简介: 【Spring】Spring常用注解(中)
IOCTest
1. public class IOCTest {
2.    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
3. 
4. 
5.    @Test
6.    public void testImport(){
7.       printBeans(applicationContext);
8.       Blue bean = applicationContext.getBean(Blue.class);
9.       System.out.println(bean);
10. 
11. //工厂Bean获取的是调用getObject创建的对象
12. Object bean2 = applicationContext.getBean("colorFactoryBean");   
13.       System.out.println("bean的类型:"+bean2.getClass()); //pos_1   输出:bean的类型:class com.atguigu.bean.Color
14. 
15. Object bean4 = applicationContext.getBean("&colorFactoryBean");
16.       System.out.println(bean4.getClass()); //pos_2  输出:class com.atguigu.bean.ColorFactoryBean
17.    }
18. 
19.    private void printBeans(AnnotationConfigApplicationContext applicationContext){
20. String[] definitionNames = applicationContext.getBeanDefinitionNames();
21. for (String name : definitionNames) {
22.          System.out.println(name);
23.       }
24.    }
25. }

输出:

//前面无关的输出省略


colorFactoryBean

ColorFactoryBean...getObject...

bean的类型:class com.atguigu.bean.Color

class com.atguigu.bean.ColorFactoryBean

生命周期

@Bean指定初始化和销毁方法

IOCTest_LifeCycle

后面的几个用的都是这个测试类

1. public class IOCTest_LifeCycle {
2. 
3.    @Test
4.    public void test01(){
5. //1、创建ioc容器
6.       AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
7.       System.out.println("容器创建完成...");
8. 
9. //applicationContext.getBean("car");
10. //关闭容器
11.       applicationContext.close();
12.    }
13. 
14. }
MainConfigOfLifeCycle
1. package com.atguigu.config;
2. 
3. import org.springframework.context.ApplicationListener;
4. import org.springframework.context.annotation.Bean;
5. import org.springframework.context.annotation.ComponentScan;
6. import org.springframework.context.annotation.Configuration;
7. import org.springframework.context.annotation.Scope;
8. 
9. import com.atguigu.bean.Car;
10. 
11. /**
12.  * bean的生命周期:
13.  *        bean创建---初始化----销毁的过程
14.  * 容器管理bean的生命周期;
15.  * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
16.  * 
17.  * 构造(对象创建)
18.  *        单实例:在容器启动的时候创建对象
19.  *        多实例:在每次获取的时候创建对象\
20.  * 初始化:
21.  *    对象创建完成,并赋值好,调用初始化方法。。。
22.  * BeanPostProcessor.postProcessAfterInitialization
23.  * 销毁:
24.  *    单实例:容器关闭的时候
25.  *    多实例:容器不会管理这个bean;容器不会调用销毁方法;
26.  * 
27.  * 1)、指定初始化和销毁方法;
28.  *        通过@Bean指定init-method和destroy-method;
29.  * @author lfy
30.  *
31.  */
32. @ComponentScan("com.atguigu.bean")
33. @Configuration
34. public class MainConfigOfLifeCycle {
35. 
36. //@Scope("prototype")
37. @Bean(initMethod="init",destroyMethod="detory")
38. public Car car(){
39. return new Car();
40.    }
41. 
42. }
43. @Component
44. public class Car {
45. 
46. public Car(){
47.       System.out.println("car constructor...");
48.    }
49. 
50. public void init(){
51.       System.out.println("car ... init...");
52.    }
53. 
54. public void detory(){
55.       System.out.println("car ... detory...");
56.    }
57. 
58. }
输出

car constructor...

car ... init...

容器创建完成

car ... detory...

InitializingBean和DisposableBean

MainConfigOfLifeCycle
1. /**
2.  * bean的生命周期:
3.  *        bean创建---初始化----销毁的过程
4.  * 容器管理bean的生命周期;
5.  * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
6.  * 
7.  * 构造(对象创建)
8.  *        单实例:在容器启动的时候创建对象
9.  *        多实例:在每次获取的时候创建对象\
10.  * 
11.  * BeanPostProcessor.postProcessBeforeInitialization
12.  * 初始化:
13.  *        对象创建完成,并赋值好,调用初始化方法。。。
14.  * BeanPostProcessor.postProcessAfterInitialization
15.  * 销毁:
16.  *        单实例:容器关闭的时候
17.  *        多实例:容器不会管理这个bean;容器不会调用销毁方法;
18.  * 
19.  * 
20.  * 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,
21.  * 一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
22.  * 
23.  * BeanPostProcessor原理
24.  * populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
25.  * initializeBean
26.  * {
27.  * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
28.  * invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
29.  * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
30.  *}
31.  * 
32.  * 
33.  * 
34.  * 1)、指定初始化和销毁方法;
35.  *        通过@Bean指定init-method和destroy-method;
36.  * 2)、通过让Bean实现InitializingBean(定义初始化逻辑),
37.  *              DisposableBean(定义销毁逻辑);
38.  * 
39.  * @author lfy
40.  *
41.  */
42. @ComponentScan("com.atguigu.bean")
43. @Configuration
44. public class MainConfigOfLifeCycle {
45. 
46. //@Scope("prototype")
47.    @Bean(initMethod="init",destroyMethod="detory")
48.    public Car car(){
49. return new Car();
50.    }
51. 
52. }
Cat
1. @Component
2. public class Cat implements InitializingBean,DisposableBean {
3. 
4. public Cat(){
5.       System.out.println("cat constructor...");
6.    }
7. 
8.    @Override
9. public void destroy() throws Exception {
10. // TODO Auto-generated method stub
11.       System.out.println("cat...destroy...");
12.    }
13. 
14.    @Override
15. public void afterPropertiesSet() throws Exception {
16. // TODO Auto-generated method stub
17.       System.out.println("cat...afterPropertiesSet...");
18.    }
19. 
20. }
输出

cat constructor...

cat...afterPropertiesSet...

car constructor...

car ... init...

容器创建完成

car ... detory...

cat...destroy...

@PostConstruct和@PreDestroy

MainConfigOfLifeCycle
1. /**
2.  * bean的生命周期:
3.  *        bean创建---初始化----销毁的过程
4.  * 容器管理bean的生命周期;
5.  * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
6.  * 
7.  * 构造(对象创建)
8.  *        单实例:在容器启动的时候创建对象
9.  *        多实例:在每次获取的时候创建对象\
10.  * 
11.  * BeanPostProcessor.postProcessBeforeInitialization
12.  * 初始化:
13.  *        对象创建完成,并赋值好,调用初始化方法。。。
14.  * BeanPostProcessor.postProcessAfterInitialization
15.  * 销毁:
16.  *        单实例:容器关闭的时候
17.  *        多实例:容器不会管理这个bean;容器不会调用销毁方法;
18.  * 
19.  * 
20.  * 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,
21.  * 一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
22.  * 
23.  * BeanPostProcessor原理
24.  * populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
25.  * initializeBean
26.  * {
27.  * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
28.  * invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
29.  * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
30.  *}
31.  * 
32.  * 
33.  * 
34.  * 1)、指定初始化和销毁方法;
35.  *        通过@Bean指定init-method和destroy-method;
36.  * 2)、通过让Bean实现InitializingBean(定义初始化逻辑),
37.  *              DisposableBean(定义销毁逻辑);
38.  * 3)、可以使用JSR250;
39.  *        @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
40.  *        @PreDestroy:在容器销毁bean之前通知我们进行清理工作
41.  * 
42.  * @author lfy
43.  *
44.  */
45. @ComponentScan("com.atguigu.bean")
46. @Configuration
47. public class MainConfigOfLifeCycle {
48. 
49. //@Scope("prototype")
50.    @Bean(initMethod="init",destroyMethod="detory")
51.    public Car car(){
52. return new Car();
53.    }
54. 
55. }
Dog
1. @Component
2. public class Dog implements ApplicationContextAware {
3. 
4. //@Autowired
5. private ApplicationContext applicationContext;
6. 
7. public Dog(){
8.       System.out.println("dog constructor...");
9.    }
10. 
11. //对象创建并赋值之后调用
12.    @PostConstruct
13. public void init(){
14.       System.out.println("Dog....@PostConstruct...");
15.    }
16. 
17. //容器移除对象之前
18.    @PreDestroy
19. public void detory(){
20.       System.out.println("Dog....@PreDestroy...");
21.    }
22. 
23.    @Override
24. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
25. // TODO Auto-generated method stub
26. this.applicationContext = applicationContext;
27.    }
28. }
输出
1. cat constructor...
2. cat...afterPropertiesSet...
3. dog constructor...
4. Dog....@PostConstruct...
5. car constructor...
6. car ... init...
7. 容器创建完成
8. car ... detory...
9. Dog....@PreDestroy...
10. cat...destroy...
11. BeanPostProcessor
12. /**
13.  * bean的生命周期:
14.  *        bean创建---初始化----销毁的过程
15.  * 容器管理bean的生命周期;
16.  * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
17.  * 
18.  * 构造(对象创建)
19.  *        单实例:在容器启动的时候创建对象
20.  *        多实例:在每次获取的时候创建对象\
21.  * 
22.  * BeanPostProcessor.postProcessBeforeInitialization
23.  * 初始化:
24.  *        对象创建完成,并赋值好,调用初始化方法。。。
25.  * BeanPostProcessor.postProcessAfterInitialization
26.  * 销毁:
27.  *        单实例:容器关闭的时候
28.  *        多实例:容器不会管理这个bean;容器不会调用销毁方法;
29.  * 
30.  * 
31.  * 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,
32.  * 一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
33.  * 
34.  * BeanPostProcessor原理
35.  * populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
36.  * initializeBean
37.  * {
38.  * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
39.  * invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
40.  * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
41.  *}
42.  * 
43.  * 
44.  * 
45.  * 1)、指定初始化和销毁方法;
46.  *        通过@Bean指定init-method和destroy-method;
47.  * 2)、通过让Bean实现InitializingBean(定义初始化逻辑),
48.  *              DisposableBean(定义销毁逻辑);
49.  * 3)、可以使用JSR250;
50.  *        @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
51.  *        @PreDestroy:在容器销毁bean之前通知我们进行清理工作
52.  * 4)、BeanPostProcessor【interface】:bean的后置处理器;
53.  *        在bean初始化前后进行一些处理工作;
54.  *        postProcessBeforeInitialization:在初始化之前工作
55.  *        postProcessAfterInitialization:在初始化之后工作
56.  * 
57.  * Spring底层对 BeanPostProcessor 的使用;
58.  *        bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxx BeanPostProcessor;
59.  * 
60.  * @author lfy
61.  *
62.  */
63. @ComponentScan("com.atguigu.bean")
64. @Configuration
65. public class MainConfigOfLifeCycle {
66. 
67. //@Scope("prototype")
68.    @Bean(initMethod="init",destroyMethod="detory")
69.    public Car car(){
70. return new Car();
71.    }
72. 
73. }
MyBeanPostProcessor
1. /**
2.  * 后置处理器:初始化前后进行处理工作
3.  * 将后置处理器加入到容器中
4.  * @author lfy
5.  */
6. @Component
7. public class MyBeanPostProcessor implements BeanPostProcessor {
8. 
9.    @Override
10.    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
11. // TODO Auto-generated method stub
12.       System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
13. return bean;
14.    }
15. 
16.    @Override
17.    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
18. // TODO Auto-generated method stub
19.       System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
20. return bean;
21.    }
22. 
23. }

输出

自己写的组件输出内容

car constructor... postProcessBeforeInitialization...car=>com.atguigu.bean.Car@5ef60048 car ... init... postProcessAfterInitialization...car=>com.atguigu.bean.Car@5ef60048 cat constructor... postProcessBeforeInitialization...cat=>com.atguigu.bean.Cat@780cb77 cat...afterPropertiesSet... postProcessAfterInitialization...cat=>com.atguigu.bean.Cat@780cb77 dog constructor... postProcessBeforeInitialization...dog=>com.atguigu.bean.Dog@4034c28c Dog....@PostConstruct... postProcessAfterInitialization...dog=>com.atguigu.bean.Dog@4034c28c 容器创建完成... Dog....@PreDestroy... cat...destroy... car ... detory...

  1. BeanPostProcessor在Spring源码里大量被使用到,仅凭这里雷丰阳老师讲的一点点原理,是无法体会的,建议自己去看看Spring源码。所以这里的原理部分我也就直接省略了,在本视频中讲的太浅了。

属性赋值

@Value和@PropertySource

Person
1. public class Person {
2. 
3. //使用@Value赋值;
4. //1、基本数值
5. //2、可以写SpEL; #{}
6. //3、可以写${};取出配置文件【properties】中的值(在运行环境变量里面的值)
7. 
8. @Value("张三")
9. private String name;
10. @Value("#{20-2}")
11. private Integer age;
12. 
13. @Value("${person.nickName}")
14. private String nickName;
15. 
16. 
17. 
18. public String getNickName() {
19. return nickName;
20.    }
21. public void setNickName(String nickName) {
22. this.nickName = nickName;
23.    }
24. public String getName() {
25. return name;
26.    }
27. public void setName(String name) {
28. this.name = name;
29.    }
30. public Integer getAge() {
31. return age;
32.    }
33. public void setAge(Integer age) {
34. this.age = age;
35.    }
36. 
37. public Person(String name, Integer age) {
38. super();
39. this.name = name;
40. this.age = age;
41.    }
42. public Person() {
43. super();
44. // TODO Auto-generated constructor stub
45.    }
46. @Override
47. public String toString() {
48. return "Person [name=" + name + ", age=" + age + ", nickName=" + nickName + "]";
49.    }
50. }
相关文章
|
7天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
25 0
|
1月前
|
Java Spring 容器
如何解决spring EL注解@Value获取值为null的问题
本文探讨了在使用Spring框架时,如何避免`@Value("${xxx.xxx}")`注解导致值为null的问题。通过具体示例分析了几种常见错误场景,包括类未交给Spring管理、字段被`static`或`final`修饰以及通过`new`而非依赖注入创建对象等,提出了相应的解决方案,并强调了理解框架原理的重要性。
124 4
|
26天前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
|
14天前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
40 4
SpringBoot必须掌握的常用注解!
|
1月前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
66 9
Spring从入门到入土(bean的一些子标签及注解的使用)
|
16天前
|
存储 缓存 Java
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
57 2
|
16天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
33 1
|
1月前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
|
11天前
|
存储 安全 Java
springboot当中ConfigurationProperties注解作用跟数据库存入有啥区别
`@ConfigurationProperties`注解和数据库存储配置信息各有优劣,适用于不同的应用场景。`@ConfigurationProperties`提供了类型安全和模块化的配置管理方式,适合静态和简单配置。而数据库存储配置信息提供了动态更新和集中管理的能力,适合需要频繁变化和集中管理的配置需求。在实际项目中,可以根据具体需求选择合适的配置管理方式,或者结合使用这两种方式,实现灵活高效的配置管理。
10 0
|
1月前
|
XML Java 数据库
Spring boot的最全注解
Spring boot的最全注解