zoukankan      html  css  js  c++  java
  • Spring注解(生命周期)

    对于上面的知识图解,需要一点一点的研究。

     首先核心容器:


     控制反转 和 依赖注入

        

    创建工程:

       maven仓库搜索 spring context  : 

     

     引入后

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.1.RELEASE</version>
    </dependency>

     

    以前是通过 application.xml 进行配置设置

    配置类 等同于以前的配置文件:

       

    package com.toov5.bean;
    
    public class Person {
      int age;
      String name;
      
    public Person() {
        
    }  
    public Person(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }
    @Override
    public String toString() {
        return "Person [age=" + age + ", name=" + name + "]";
    }
    
    }

    config:

    package com.toov5.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import com.toov5.bean.Person;
    
    @Configuration
    public class config {
       
        @Bean //给容器注册一个Bean,类型为返回值的类型。xml中的id是用方法作为id
        public Person person() {
            return new Person(1, "toov5");
        }
    }

    测试类:

    package com.toov5.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import com.toov5.bean.Person;
    import com.toov5.config.config;
    
    public class test {
    
        public static void main(String[] args) {
    
            @SuppressWarnings("resource")
            ApplicationContext applicationContex = new AnnotationConfigApplicationContext(config.class); // 之前是传递配置文件的位置
                                                                                                            // 现在是我们设计的配置类的位置
            Person bean = applicationContex.getBean(Person.class); // 通过类型去获取
            System.out.println(bean);
    
            String[] beanNamesForType = applicationContex.getBeanNamesForType(Person.class); // 根据类型找到bean的名字
            for (String name : beanNamesForType) {
                System.out.println(name); // 返回bean的名字 我们可以在cofig中配置@Bean的名字
            }
    
        }
    
    }

    在xml配置的时候,我们使用的是包扫描的方式

     <context: component-scan base-package= "com.toov5"> </context: conponent-scan>

     包扫描: 只要标注了 @Controller @Service @Repository  @Component

    用注解搞定:  @ComponentScan(value="com.toov5.bean")

    可以指定要扫描的包 

    排除的包,包括可以按照 名字 按照类型等去排除   excludeFilters    

    指定的包,指定扫描的时候只需要包含哪些组件     includeFilters

    还可以通过自定义规则 CUSTOM 通过 implements TypeFilter 重写match方法

       metadataReader : 读取到的当前正在扫描的类的信息

       metadataReaderFactory: 可以获取到其他任何类

    config:

    package com.toov5.config;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.ComponentScan.Filter;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.stereotype.Controller;
    import org.springframework.stereotype.Service;
    
    @Configuration   //标记@Service 和 @Controller的
      @ComponentScan(value="com.toov5",excludeFilters = {
              @Filter(type=FilterType.ANNOTATION,classes= { Controller.class,Service.class })})
    //@ComponentScan(value="com.toov5")
    public class config {
       
        
    }

     controller

    package com.toov5.controller;
    
    import org.springframework.stereotype.Controller;
    
    @Controller
    public class BookController {
       
    }

    Service

    package com.toov5.service;
    
    import org.springframework.stereotype.Service;
    
    @Service
    public class BookService {
       
    }

    Dao

    package com.toov5.dao;
    
    import org.springframework.stereotype.Repository;
    
    @Repository
    public class BookDao {
    
    }

    测试:

    package com.toov5.test;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import com.toov5.config.config;
    
    public class test {
       
        @SuppressWarnings("resource")
        @Test
        public void test01(){
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
            String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
            for(String name : beanDefinitionNames) {
                System.out.println(name);
            }
        }
        
    }

     config类:

    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.ComponentScan.Filter;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.stereotype.Controller;
    import org.springframework.stereotype.Service;
    
    @Configuration   //标记@Service 和 @Controller的
      @ComponentScan(value="com.toov5",excludeFilters = {
    //          @Filter(type=FilterType.ANNOTATION,classes= { Controller.class,Service.class }),
              @Filter(type=FilterType.CUSTOM, classes= {MyTypeFilter.class})
              
             })
    //@ComponentScan(value="com.toov5")
    public class config {
       
        
    }

    自定义的:

    package com.toov5.config;
    
    import java.io.IOException;
    
    import org.springframework.core.io.Resource;
    import org.springframework.core.type.AnnotationMetadata;
    import org.springframework.core.type.ClassMetadata;
    import org.springframework.core.type.classreading.MetadataReader;
    import org.springframework.core.type.classreading.MetadataReaderFactory;
    
    public class MyTypeFilter implements org.springframework.core.type.filter.TypeFilter{
    
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
                throws IOException {
            //获取当前类注解的信息
            AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
            //获取当前正在扫描的类的类信息
            ClassMetadata classMetadata = metadataReader.getClassMetadata();
            //获取当前资源(类路径)
             Resource resource = metadataReader.getResource();
             // 获取到类名
             String className = classMetadata.getClassName();
             System.out.println("---->"+className);
             return false;
        }
          
        
    }

     运行结果:

     

    可以继续往下玩儿:

    package com.toov5.config;
    
    import java.io.IOException;
    
    import org.springframework.core.io.Resource;
    import org.springframework.core.type.AnnotationMetadata;
    import org.springframework.core.type.ClassMetadata;
    import org.springframework.core.type.classreading.MetadataReader;
    import org.springframework.core.type.classreading.MetadataReaderFactory;
    
    public class MyTypeFilter implements org.springframework.core.type.filter.TypeFilter{
    
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
                throws IOException {
            //获取当前类注解的信息
            AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
            //获取当前正在扫描的类的类信息
            ClassMetadata classMetadata = metadataReader.getClassMetadata();
            //获取当前资源(类路径)
             Resource resource = metadataReader.getResource();
             // 获取到类名
             String className = classMetadata.getClassName();
             System.out.println("---->"+className);
             //加入校验逻辑
             if (className.contains("er")) {
                return true;   //匹配成功
            }
             return false;
        }
          
    }

    @Scope 设置作用域 

        config:

    package com.toov5.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    import com.toov5.Bean.Person;
    
    @Configuration   //标记@Service 和 @Controller的
    @ComponentScan(value="com.toov5")
    public class config {
       
        @Bean
        public Person person() {
            return new Person(12,"toov5");
        }
    }

      Test:

    package com.toov5.test;
    import org.junit.Test;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import com.toov5.config.config;
    
    public class test {
       
        @SuppressWarnings("resource")
        @Test
        public void test01(){
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
            String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
            for(String name : beanDefinitionNames) {
                System.out.println(name);
            }
            //comfig 的@Bean 默认是单例的
            Object p1 = applicationContext.getBean("person");
            Object p2 = applicationContext.getBean("person");
            System.out.println( p1==p2);
        }
        
    }

    prototype: 多实例的

    singleton: 单实例的(默认的)

    request: 同一次请求创建一个实例

    session: 同一个session创建一个实例

    @Configuration   //标记@Service 和 @Controller的
    @ComponentScan(value="com.toov5")
    public class config {
       
        @Bean
        @Scope("prototype")
        public Person person() {
            return new Person(12,"toov5");
        }
    }

     单例情况下:

      

    public class config {
       
        @Bean(name="people")
        @Scope()
        public Person person() {
            System.out.println("容器创建....");
            return new Person(12,"toov5");
        }
    }

    测试类启动ioc容器:

    public class test {
       
        @SuppressWarnings("resource")
        @Test
        public void test01(){
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
    
        }
        
    }

    单例模式,ioc容器启动后会调用方法创建对象放到IOC容器总  以后每次获取就是直接从容器中获取. 类似于从map获取 map.get()

    如果是多例模式:

     ioc容器启动是不会创建对象的!

    只有调用时候,并且调用一次,获取一次 调用方法创建对象

     config:

    @Configuration   //标记@Service 和 @Controller的
    @ComponentScan(value="com.toov5")
    public class config {
       
        @Bean(name="people")
        @Scope("prototype")
        public Person person() {
            System.out.println("容器创建....");
            return new Person(12,"toov5");
        }
    }
    public class test {
       
        @SuppressWarnings("resource")
        @Test
        public void test01(){
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
            System.out.println("IOC容器创建完成");
            Object p1 = applicationContext.getBean("people");
            System.out.println(p1);
            Object p2 = applicationContext.getBean("people");
            System.out.println(p2);
        }
        
    }

    @Lazy

     懒加载: 单实例bean,默认在容器启动的时候创建对象,懒加载容器启动时候先不创建。第一次在使用获取Bean时候才创建对象,并且进行初始化。

    config:

    @Configuration   //标记@Service 和 @Controller的
    @ComponentScan(value="com.toov5")
    public class config {
       
        @Bean(name="people")
        @Lazy
        public Person person() {
            System.out.println("容器创建....");
            return new Person(12,"toov5");
        }
    }

    测试:

    public class test {
       
        @SuppressWarnings("resource")
        @Test
        public void test01(){
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
            System.out.println("IOC容器创建完成");
            Object p1 = applicationContext.getBean("people");
            System.out.println(p1);
            Object p2 = applicationContext.getBean("people");
            System.out.println(p2);
        }
        
    }

     第一次获取时候加载。只创建一次。

     @Condition 按照条件注册bean

        也是springboot 底层大量使用的。 按照一定条件进行判断,满足条件给容器注册Bean

     原来情况:

    @Configuration   //标记@Service 和 @Controller的
    @ComponentScan(value="com.toov5")
    public class config {
       
        @Bean(name="Jack")
        public Person person1() {
            System.out.println("容器创建....");
            return new Person(50,"马云");
        }
        
        @Bean(name="Linux")
        public Person person2() {
            System.out.println("容器创建....");
            return new Person(51,"Linux");
        }
        
    }

    测试:

    import com.toov5.Bean.Person;
    import com.toov5.config.config;
    
    public class test {
       
        @SuppressWarnings("resource")
        @Test
        public void test01(){
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
           String[] beanNamesForType = applicationContext.getBeanNamesForType(Person.class);
           for(String name : beanNamesForType) {
               System.out.println(name);
           }
        }
        
    }

    打印:

    要求:

    如果操作系统是win10 被容器注册 linux

    如果是linux  给容器注册 马云

     代码:

    public class test {
       
        @SuppressWarnings("resource")
        @Test
        public void test01(){
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
            ConfigurableEnvironment environment = applicationContext.getEnvironment();
            String osName  = environment.getProperty("os.name"); 
            System.out.println(osName);
        
        }
        
    }

    打印:

     

    动态获取环境变量的值

    context的巧用:

        // 能获取到ioc使用的beanfactory
            ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
            //获取到类加载器
            ClassLoader classLoader = context.getClassLoader();
            //获取到bean定义的注册类 能创建 获取 查询 bean 的定义
            BeanDefinitionRegistry registry = context.getRegistry();

    config:

    @Configuration   
    public class config {
        
        @Conditional({WindowsCondition.class})
        @Bean(name="Windows")
        public Person person1() {
            System.out.println("容器创建....");
            return new Person(50,"Windows");
        }
         
        @Conditional({LinuxCondition.class})
        @Bean(name="Linux")
        public Person person2() {
            System.out.println("容器创建....");
            return new Person(51,"Linux");
        }
        
    }

    条件:

    public class LinuxCondition implements Condition{
      
        // ConditionContext  判断条件能使用的上下文
        // AnnotatedTypeMetadata 注释信息
        
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            //判断是否linux 系统    
            //运行时环境信息
            Environment environment = context.getEnvironment();
            String property = environment.getProperty("os.name");
            if (property.contains("Linux")) {
                return true;
            }
            return false;
        }
    
    }

    条件:

    public class WindowsCondition implements Condition {
    
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            Environment environment = context.getEnvironment();
            String property = environment.getProperty("os.name");
            if (property.contains("Windows")) {
                return true;
            }
            return false;
        }
       
    }

     测试:

    public class test {
       
        @SuppressWarnings("resource")
        @Test
        public void test01(){
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
           String[] beanNamesForType = applicationContext.getBeanNamesForType(Person.class);
           for(String name : beanNamesForType) {
               System.out.println(name);
           }
        }
        
    }

    可以做更多的判断,更多的条件

      

    public class WindowsCondition implements Condition {
    
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            Environment environment = context.getEnvironment();
            String property = environment.getProperty("os.name");
            if (property.contains("Windows")) {
                return true;
            }
            
            BeanDefinitionRegistry registry = context.getRegistry();
            boolean result = registry.containsBeanDefinition("Windows"); //容器中是否包含Windows
            // registry 判断没有 可以自己注册一个 非常多的判断条件 也可以给容器中注册bean
            
            
            return false;
        }
       
    }

    @Condition还可以标注在类上面, 满足当前条件 这个类 中配置的所有Bean注册才能生效

    @Configuration  
    @Conditional({WindowsCondition.class})
    public class config {
            
        @Bean(name="Windows")
        public Person person1() {
            System.out.println("容器创建....");
            return new Person(50,"Windows");
        }
         
        @Bean(name="Linux")
        public Person person2() {
            System.out.println("容器创建....");
            return new Person(51,"Linux");
        }
        
    }

    打印:

    给容器中注册组件:

     1、 包+组件标注-@Controller @Service  @Repository @Component

     如果导入第三方包呢?

     2、 别人写类: @Bean 导入的第三方包里面的组件

     3、 @Import   快速给容器中导入一个组件  id默认全类名

           @ImportSelector  返回需要导入的组件的全类名数组

     4、Spring提供的FactoryBean

    测试:

    public class test {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
       
        private void printBeans(AnnotationConfigApplicationContext applicationContext) {
            String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
            for(String name : beanDefinitionNames) {
                System.out.println(name);
            }
        }
        
        @Test
        public void test01(){  
            printBeans(applicationContext);
        }
        
    }

    查看Ioc中的bean组件:

     除了ioc自己的,还有那几个正常的

     

    这么玩儿:

    package com.toov5.Bean;
    
    public class Animal {
      String  color ;
      String  name;
      public Animal() {
        // TODO Auto-generated constructor stub
    }
    public Animal(String color, String name) {
        super();
        this.color = color;
        this.name = name;
    }
      
    }

    config:

    public class test {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
       
        private void printBeans(AnnotationConfigApplicationContext applicationContext) {
            String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
            for(String name : beanDefinitionNames) {
                System.out.println(name);
            }
        }
        
        @Test
        public void test01(){  
            printBeans(applicationContext);
        }
        
    }

    结果:

     如果导入多个 ,可以用数组形式@Import({A.class, B.class})

     id 默认是全类名

    config:

    @Configuration  
    @Conditional({WindowsCondition.class})
    @Import( {Animal.class , MyImportSelector.class})
    public class config {    
        @Bean(name="Windows")
        public Person person1() {
            System.out.println("容器创建....");
            return new Person(50,"Windows");
        }     
        @Bean(name="Linux")
        public Person person2() {
            System.out.println("容器创建....");
            return new Person(51,"Linux");
        }    
    }

    类:

    //自定义逻辑 返回需要导入的组件
    public class MyImportSelector  implements ImportSelector{
       //返回值,就是要导入到容器中的组件全类名
      // AnnotationMetadata: 当前标注@Import注解的类的所有注解信息     
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    
            return new String[] {"com.toov5.Bean.Fruit"} ;
        }
    
    }

    结果:

     

    从容器中获取之:

    public class test {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
       
        private void printBeans(AnnotationConfigApplicationContext applicationContext) {
            String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
            for(String name : beanDefinitionNames) {
                System.out.println(name);
            }
        }
        
        @Test
        public void test01(){  
            printBeans(applicationContext);
            Object bean = applicationContext.getBean(Fruit.class);
            System.out.println(bean);
        }
        
    }

    结果:

    业务判断:

    public class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar{
        //AnnotationMetadata 当前类的注解信息 和 其他信息
        // BeanDefinitionRegistry: BeanDefinition注册类
            //可以调用BeanDefinitionRegistry方法,自定义来注册Bean组件到容器中
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            //写逻辑
            Boolean result =registry.containsBeanDefinition("com.toov5.Bean.Fruit"); //容器中是否有电脑
            if (result) { //判断逻辑
                //指定bean的定义信息 包括scope等等
                RootBeanDefinition beanDefinition = new RootBeanDefinition(Pen.class);
                //向容器中注册bean的名字
                registry.registerBeanDefinition("pen", beanDefinition);
            }
        }
    
    }

    配置:

    @Configuration  
    @Conditional({WindowsCondition.class})
    @Import( {Animal.class , MyImportSelector.class, MyImportBeanDefinitionRegister.class})
    public class config {    
        @Bean(name="Windows")
        public Person person1() {
            System.out.println("容器创建....");
            return new Person(50,"Windows");
        }     
        @Bean(name="Linux")
        public Person person2() {
            System.out.println("容器创建....");
            return new Person(51,"Linux");
        }    
    }

    测试:

    public class test {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
       
        private void printBeans(AnnotationConfigApplicationContext applicationContext) {
            String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
            for(String name : beanDefinitionNames) {
                System.out.println(name);
            }
        }
        
        @Test
        public void test01(){  
            printBeans(applicationContext);
            Object bean = applicationContext.getBean(Fruit.class);
            System.out.println(bean);
        }
        
    }

    FactoryBean 工厂Bean  区别普通的Bean,导入到容器中,容器会调用无参构造器,然后创建一个对象注册到的容器中

    工厂Bean 是个工厂, 是个接口

    容器调用:

     

    返回对象给容器 

     还有两个方法:

       

     

    创建一个 Pen 的工厂Beran

       

    import org.springframework.beans.factory.FactoryBean;
    
    import com.toov5.Bean.Pen;
    
    //创建一个spring 定义的工厂bean
    public class PenFactoryBean  implements FactoryBean<Pen>{
        //返回的对象会添加到容器中
        public Pen getObject() throws Exception {
            // TODO Auto-generated method stub
            System.out.println("PenFactoryBean---getBean---");
            return new Pen();
        }
    
        public Class<?> getObjectType() {
            // TODO Auto-generated method stub
            return Pen.class;
        }
       
        //如果是单例(true) 则在容器中只会保存一份
        public boolean isSingleton() {
            // TODO Auto-generated method stub
            return false;
        }
       //如果是false  则每次获取都会创建新的  即调用 getObject 方法
    }

    然后将工厂bean 加入到容器

    @Configuration  
    @Import( {Animal.class , MyImportSelector.class, MyImportBeanDefinitionRegister.class})
    public class config {    
        
        @Bean
        public PenFactoryBean penFactoryBean() {
            return new PenFactoryBean();
        }
    }

    工厂Bean 获取的是调用getObject创建的对象  

    public class test {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(config.class);
       
        private void printBeans(AnnotationConfigApplicationContext applicationContext) {
            String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
            for(String name : beanDefinitionNames) {
                System.out.println(name);
            }
        }
        
        @Test 
        public void test01(){  
            printBeans(applicationContext);
            Object bean1 = applicationContext.getBean("penFactoryBean");
            Object bean2 = applicationContext.getBean("penFactoryBean");
            System.out.println(bean1==bean2);
            
            Object bean3 = applicationContext.getBean("&penFactoryBean");
            System.out.println(bean3); //加&获取到工厂bean调用getObject创建的对象
                                       //要获取工厂Bean本身,需要id前面加& 否则就是工厂bean的本身了
        }
    }

    打印:

    在于其他第三方框架整合时候 FactoryBean用的很多

    方法一: Bean生命周期,Bean创建到初始化,到销毁的过程。由容器管理。

      初始化 和 销毁的方法可以自定义

    xml配置中 通过  init-method  destory-method  配置方法指定

    方法二: 注解中:  

       构造(对象创建)

         单例: 在容器启动的时候创建

         多例:在每次获取的时候创建

    对于生命周期的方法声明,用注解:

      Bean: @Bean(initMethod="init", destroyMethod="destory") 

       

    public class Car {
      public Car() {
        System.out.println("无参构造初始化");
    }
      public void init() {
        System.out.println("CarBean---init");
    } 
      public void destory() {
        System.out.println("CarBean---destory");
      }
    }

     config:

    @Configuration
    public class BeanLife {
       
        @Bean(initMethod="init", destroyMethod="destory") 
        public Car car() {
            return new Car();    
        }
        
    }

    测试方法:

    @Test 
        public void test01(){  
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanLife.class);
            System.out.println("容器创建完成");
        }

    结果:

    关闭容器:

     @Test 
        public void test01(){  
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanLife.class);
            System.out.println("容器创建完成");
            //关闭容器
            applicationContext.close();
        }

     在数据源的配置过程中 有很多属性的配置需要用到 销毁时候 关闭连接等等

      总结:

        初始化, 对象创建完成,并赋值,调用初始化方法

        销毁, 容器关闭时候。 但是如果是多例情况,创建对象是获取时候才会执行。销毁时候,是不进行的。容器不管的。

     方法三: Spring 还提供了两个接口: Bean通过实现InitializingBean (定义初始化逻辑)

                                                                                        DisposableBean (定义销毁逻辑)

     Bean:

    @Component
    public class Cat implements InitializingBean, DisposableBean{
      
        public Cat() {
            System.out.println("cat 构造函数...");
        }
      //销毁方法
        public void destroy() throws Exception {
            System.out.println("cat destory");
            
        }
      //初始化方法
        public void afterPropertiesSet() throws Exception {
            System.out.println("cat afterPropertiesSet");
            
        }
    
    }

    配置:

    @ComponentScan("com.toov5.Bean")
    @Configuration
    public class BeanLife {
        
        @Bean(initMethod="init", destroyMethod="destory") 
        public Car car() {
            return new Car();    
        }
        
    }

    测试:

    @Test 
        public void test01(){  
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanLife.class);
            System.out.println("容器创建完成");
            //关闭容器
            applicationContext.close();
        }

    还可以使用: JSP250规范的   @PostConstruct   在bean创建完成 并且属性赋值完成执行初始化 

                                                      @Predestory  当bean从容器中销毁Bean之前 通知清理工作

     Bean:

    @Component
    public class Cat implements InitializingBean, DisposableBean{
      
        public Cat() {
            System.out.println("cat 构造函数...");
        }
      //销毁方法
        public void destroy() throws Exception {
            System.out.println("cat destory");
            
        }
      //初始化方法
        public void afterPropertiesSet() throws Exception {
            System.out.println("cat afterPropertiesSet");
            
        }
    
    }

    config:

    @ComponentScan("com.toov5.Bean")
    @Configuration
    public class BeanLife {
        
        @Bean(initMethod="init", destroyMethod="destory") 
        public Car car() {
            return new Car();    
        }
        
    }

    test:

     @Test 
        public void test01(){  
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanLife.class);
            System.out.println("容器创建完成");
            //关闭容器
            applicationContext.close();
        }

    结果:

     还可以使用interface  BeanPostProcessor: 在bean初始化前后进行一些处理工作

         postProcessBeforeInitialization( )   初始化之前工作

         postProcessAfterInitialization( )      初始化之后工作

        后置处理器:  初始化前后进行处理工作

         

        

          每个bean在初始化init之前调用 postProcessBeforeInitialization  

                              初始化init 之后调用 postProcessAfterInitialization 

         

       

     对于Bean 的生命周期:

      构造器初始化, 初始化(可以自定义指定),初始化前后可以使用(BeanPostProcessor)进行拦截。 销毁(自定义执行)

    关于BeanPostProcessor 在Spring 底层的使用

         

    @Component
    public class Dog implements ApplicationContextAware{
    
        private ApplicationContext applicationContext;
        
       public Dog() {
        System.out.println("dog 构造函数初始化");
      }
       
       @PostConstruct
       public void init() {
           System.out.println("对象创建 并且赋值之后 调用了 @PostConstruct");
       }
       
       @PreDestroy
       public void destory() {
          System.out.println("容器关闭 移除bean,调用了 @PreDestroy");  
       }
    
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        //dog对象被创建后 ioc容器会被传递进来
        this.applicationContext=applicationContext;    
    } 
    }

    BeanValidationPostProcessor

        可以做数据校验, 当对象创建完 给Bean赋值以后。做数据校验

    还有

    InitDestoryAnnottionBeanPostProcessor

     AutowiredAnnotationBeanPostProcessor    对象创建完了之后 处理所有 @Autowried标注的属性

    小结: BeanPostProcessor 接口 : bean赋值,注入其他组件,@Autowried,生命周期注解,@Async 等等

      

  • 相关阅读:
    【原】手写梯度下降《三》之
    【原】特征/SVD分解(图像压缩)/PCA降维简介
    【原】手写梯度下降《二》之
    【原】手写梯度下降《一》之
    Python守护进程和脚本单例运行
    subprocess popen 子进程退出的问题
    subprocess.Popen 详解
    python可以序列化的对象
    concurrent.futures的一些经验
    详解multiprocessing多进程-Pool进程池模块
  • 原文地址:https://www.cnblogs.com/toov5/p/10652567.html
Copyright © 2011-2022 走看看