【Spring】Spring常用注解(中)

Java
38
0
0
2024-06-11
标签   Spring
IOCTest
public class IOCTest {
   AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
   
   
   @Test
   public void testImport(){
      printBeans(applicationContext);
      Blue bean = applicationContext.getBean(Blue.class);
      System.out.println(bean);
      
      //工厂Bean获取的是调用getObject创建的对象
      Object bean2 = applicationContext.getBean("colorFactoryBean");   
      System.out.println("bean的类型:"+bean2.getClass()); //pos_1   输出:bean的类型:class com.atguigu.bean.Color
      
      Object bean4 = applicationContext.getBean("&colorFactoryBean");
      System.out.println(bean4.getClass()); //pos_2  输出:class com.atguigu.bean.ColorFactoryBean
   }
   
   private void printBeans(AnnotationConfigApplicationContext applicationContext){
      String[] definitionNames = applicationContext.getBeanDefinitionNames();
      for (String name : definitionNames) {
         System.out.println(name);
      }
   }
}

输出:

//前面无关的输出省略

colorFactoryBean
ColorFactoryBean...getObject...
bean的类型:class com.atguigu.bean.Color
class com.atguigu.bean.ColorFactoryBean
生命周期
@Bean指定初始化和销毁方法
IOCTest_LifeCycle
后面的几个用的都是这个测试类
public class IOCTest_LifeCycle {
   
   @Test
   public void test01(){
      //1、创建ioc容器
      AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
      System.out.println("容器创建完成...");
      
      //applicationContext.getBean("car");
      //关闭容器
      applicationContext.close();
   }

}
MainConfigOfLifeCycle
package com.atguigu.config;

import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import com.atguigu.bean.Car;

/**
 * bean的生命周期:
 *        bean创建---初始化----销毁的过程
 * 容器管理bean的生命周期;
 * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
 * 
 * 构造(对象创建)
 *        单实例:在容器启动的时候创建对象
 *        多实例:在每次获取的时候创建对象\
 * 初始化:
 * 		对象创建完成,并赋值好,调用初始化方法。。。
 * BeanPostProcessor.postProcessAfterInitialization
 * 销毁:
 * 		单实例:容器关闭的时候
 * 		多实例:容器不会管理这个bean;容器不会调用销毁方法;
 * 
 * 1)、指定初始化和销毁方法;
 *        通过@Bean指定init-method和destroy-method;
 * @author lfy
 *
 */
@ComponentScan("com.atguigu.bean")
@Configuration
public class MainConfigOfLifeCycle {
   
   //@Scope("prototype")
   @Bean(initMethod="init",destroyMethod="detory")
   public Car car(){
      return new Car();
   }

}
@Component
public class Car {
   
   public Car(){
      System.out.println("car constructor...");
   }
   
   public void init(){
      System.out.println("car ... init...");
   }
   
   public void detory(){
      System.out.println("car ... detory...");
   }

}
输出
car constructor...
car ... init...
容器创建完成
car ... detory...
InitializingBean和DisposableBean
MainConfigOfLifeCycle


/**
 * bean的生命周期:
 *        bean创建---初始化----销毁的过程
 * 容器管理bean的生命周期;
 * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
 * 
 * 构造(对象创建)
 *        单实例:在容器启动的时候创建对象
 *        多实例:在每次获取的时候创建对象\
 * 
 * BeanPostProcessor.postProcessBeforeInitialization
 * 初始化:
 *        对象创建完成,并赋值好,调用初始化方法。。。
 * BeanPostProcessor.postProcessAfterInitialization
 * 销毁:
 *        单实例:容器关闭的时候
 *        多实例:容器不会管理这个bean;容器不会调用销毁方法;
 * 
 * 
 * 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,
 * 一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
 * 
 * BeanPostProcessor原理
 * populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
 * initializeBean
 * {
 * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 * invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
 * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 *}
 * 
 * 
 * 
 * 1)、指定初始化和销毁方法;
 *        通过@Bean指定init-method和destroy-method;
 * 2)、通过让Bean实现InitializingBean(定义初始化逻辑),
 *              DisposableBean(定义销毁逻辑);
 * 
 * @author lfy
 *
 */
@ComponentScan("com.atguigu.bean")
@Configuration
public class MainConfigOfLifeCycle {
   
   //@Scope("prototype")
   @Bean(initMethod="init",destroyMethod="detory")
   public Car car(){
      return new Car();
   }

}
Cat
@Component
public class Cat implements InitializingBean,DisposableBean {
   
   public Cat(){
      System.out.println("cat constructor...");
   }

   @Override
   public void destroy() throws Exception {
      // TODO Auto-generated method stub
      System.out.println("cat...destroy...");
   }

   @Override
   public void afterPropertiesSet() throws Exception {
      // TODO Auto-generated method stub
      System.out.println("cat...afterPropertiesSet...");
   }

}
输出
cat constructor...
cat...afterPropertiesSet...
car constructor...
car ... init...
容器创建完成
car ... detory...
cat...destroy...
@PostConstruct和@PreDestroy
MainConfigOfLifeCycle
/**
 * bean的生命周期:
 *        bean创建---初始化----销毁的过程
 * 容器管理bean的生命周期;
 * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
 * 
 * 构造(对象创建)
 *        单实例:在容器启动的时候创建对象
 *        多实例:在每次获取的时候创建对象\
 * 
 * BeanPostProcessor.postProcessBeforeInitialization
 * 初始化:
 *        对象创建完成,并赋值好,调用初始化方法。。。
 * BeanPostProcessor.postProcessAfterInitialization
 * 销毁:
 *        单实例:容器关闭的时候
 *        多实例:容器不会管理这个bean;容器不会调用销毁方法;
 * 
 * 
 * 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,
 * 一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
 * 
 * BeanPostProcessor原理
 * populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
 * initializeBean
 * {
 * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 * invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
 * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 *}
 * 
 * 
 * 
 * 1)、指定初始化和销毁方法;
 *        通过@Bean指定init-method和destroy-method;
 * 2)、通过让Bean实现InitializingBean(定义初始化逻辑),
 *              DisposableBean(定义销毁逻辑);
 * 3)、可以使用JSR250;
 *        @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
 *        @PreDestroy:在容器销毁bean之前通知我们进行清理工作
 * 
 * @author lfy
 *
 */
@ComponentScan("com.atguigu.bean")
@Configuration
public class MainConfigOfLifeCycle {
   
   //@Scope("prototype")
   @Bean(initMethod="init",destroyMethod="detory")
   public Car car(){
      return new Car();
   }

}
Dog
@Component
public class Dog implements ApplicationContextAware {
   
   //@Autowired
   private ApplicationContext applicationContext;
   
   public Dog(){
      System.out.println("dog constructor...");
   }
   
   //对象创建并赋值之后调用
   @PostConstruct
   public void init(){
      System.out.println("Dog....@PostConstruct...");
   }
   
   //容器移除对象之前
   @PreDestroy
   public void detory(){
      System.out.println("Dog....@PreDestroy...");
   }

   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
      // TODO Auto-generated method stub
      this.applicationContext = applicationContext;
   }
}
输出
cat constructor...
cat...afterPropertiesSet...
dog constructor...
Dog....@PostConstruct...
car constructor...
car ... init...
容器创建完成
car ... detory...
Dog....@PreDestroy...
cat...destroy...
BeanPostProcessor
/**
 * bean的生命周期:
 *        bean创建---初始化----销毁的过程
 * 容器管理bean的生命周期;
 * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
 * 
 * 构造(对象创建)
 *        单实例:在容器启动的时候创建对象
 *        多实例:在每次获取的时候创建对象\
 * 
 * BeanPostProcessor.postProcessBeforeInitialization
 * 初始化:
 *        对象创建完成,并赋值好,调用初始化方法。。。
 * BeanPostProcessor.postProcessAfterInitialization
 * 销毁:
 *        单实例:容器关闭的时候
 *        多实例:容器不会管理这个bean;容器不会调用销毁方法;
 * 
 * 
 * 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,
 * 一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
 * 
 * BeanPostProcessor原理
 * populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
 * initializeBean
 * {
 * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 * invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
 * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 *}
 * 
 * 
 * 
 * 1)、指定初始化和销毁方法;
 *        通过@Bean指定init-method和destroy-method;
 * 2)、通过让Bean实现InitializingBean(定义初始化逻辑),
 *              DisposableBean(定义销毁逻辑);
 * 3)、可以使用JSR250;
 *        @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
 *        @PreDestroy:在容器销毁bean之前通知我们进行清理工作
 * 4)、BeanPostProcessor【interface】:bean的后置处理器;
 *        在bean初始化前后进行一些处理工作;
 *        postProcessBeforeInitialization:在初始化之前工作
 *        postProcessAfterInitialization:在初始化之后工作
 * 
 * Spring底层对 BeanPostProcessor 的使用;
 *        bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxx BeanPostProcessor;
 * 
 * @author lfy
 *
 */
@ComponentScan("com.atguigu.bean")
@Configuration
public class MainConfigOfLifeCycle {
   
   //@Scope("prototype")
   @Bean(initMethod="init",destroyMethod="detory")
   public Car car(){
      return new Car();
   }

}
MyBeanPostProcessor


/**
 * 后置处理器:初始化前后进行处理工作
 * 将后置处理器加入到容器中
 * @author lfy
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

   @Override
   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      // TODO Auto-generated method stub
      System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
      return bean;
   }

   @Override
   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      // TODO Auto-generated method stub
      System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
      return bean;
   }

}

输出

自己写的组件输出内容
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
public class Person {
   
   //使用@Value赋值;
   //1、基本数值
   //2、可以写SpEL; #{}
   //3、可以写${};取出配置文件【properties】中的值(在运行环境变量里面的值)
   
   @Value("张三")
   private String name;
   @Value("#{20-2}")
   private Integer age;
   
   @Value("${person.nickName}")
   private String nickName;
   
   
   
   public String getNickName() {
      return nickName;
   }
   public void setNickName(String nickName) {
      this.nickName = nickName;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public Integer getAge() {
      return age;
   }
   public void setAge(Integer age) {
      this.age = age;
   }
   
   public Person(String name, Integer age) {
      super();
      this.name = name;
      this.age = age;
   }
   public Person() {
      super();
      // TODO Auto-generated constructor stub
   }
   @Override
   public String toString() {
      return "Person [name=" + name + ", age=" + age + ", nickName=" + nickName + "]";
   }
}