Spring注解(生命周期)

Spring学习-Bean的生命周期以及注解操作 Spring是一个使用JavaBean,全方位整合各个组件,实现一站式开发的企业级应用的框架,说白了,就是一个兼容器,兼容各种开发的组件使得开发便捷高效!上面拓展后的bean加载对应的接口,然后演示bean生命周期 阅读详情

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 等等

 

 

  

 

posted @ 2019-04-04 00:10 toov5 阅读(...) 评论(...) 编辑 收藏

Windows/Linux双平台实战:QtCreator构建套件配置全攻略(含GCC/G++/GDB/CMake) 本文详细介绍了在Windows和Linux双平台下配置QtCreator构建套件的完整流程,涵盖GCC/G++、GDB和CMake等核心工具链的设置技巧。通过分步指导和实用示例,帮助开发者解决跨平台开发中的配置难题,提升Qt应用开发效率。特别针对QtCreator新手和需要在多平台切换的开发者提供了全面的配置指南。 阅读详情

相关推荐

王珊数据库系统概论第5版视频教材

目录 隐藏 说明:本课程共包括1种电子书、84个高清视频(共68课时)、1种纸质书(赠品)。 网授课程 王珊《数据库系统概论》(第5版)网授精讲班【共68课时】 序号 名称 课时 1 第1章 绪 论(1) 00:32:25 2 第1章 绪 论(2) 00:17:03 3 第1章 绪 论(3) 00:50:19 4 第1章 绪 论(4) 00:20:37 5 第1章 绪 论(5) 00:24:47 6 第2章 关系数据库(1) 00:47:23 7 第2章 关系数据库(2) 00:14:48 8 第2章 关系

mrtaoy96的博客 1147

Spring的生命周期

在使用Spring框架时,我们需要根据实际需求,合理地配置Bean的生命周期和初始化方法,以保证系统的稳定性和性能。在实例化阶段,Spring框架会创建Bean实例,并根据Bean的定义,注入Bean的属性和依赖关系。在实例化阶段完成后,Spring框架会对Bean进行初始化。在初始化阶段,Spring框架会调用Bean的初始化方法,并执行各种初始化操作,例如数据源的初始化、连接的建立等。在销毁阶段,Spring框架会调用Bean的销毁方法,并执行各种清理操作,例如数据源的关闭、连接的释放等。

MRZHQ的博客 7624

ICC 实战解析——CTS 时钟树综合中的关键设置与优化策略

本文深入解析ICC工具中CTS时钟树综合的关键设置与优化策略,涵盖时钟树异常引脚设置、目标参数配置、非默认布线规则(NDR)等核心技术。通过实战案例展示如何有效控制时钟偏差、优化信号完整性,并平衡功耗与面积,为芯片物理设计提供专业指导。

weixin_30872577的博客 325

【spring注解】3.spring生命周期相关注解

文章目录1. 什么是bean的生命周期2. 四种方式定义bean的初始化及销毁方法2.1 @Bean指定初始化及销毁方法使用场景单实例bean初始化及销毁方法的调用时机多实例bean初始化及销毁方法的调用时机2.2 让Bean实现InitializingBean及DisposableBean接口2.3 @PostConstruct和@PreDestroy注解定义初始化及销毁方法2.4 BeanPo...

右手边的流年 1354

48V电动车电池包拆解:硬核入门BMS硬件设计与故障排查

BMS(电池管理系统)是锂电应用的核心安全与性能保障模块,其本质是融合电化学、模拟电路、嵌入式控制与热管理的交叉系统。理解BMS不能止步于SOC算法或通信协议,而需回归硬件本体——从电压采样精度、MOSFET驱动时序、被动均衡散热设计到NTC热耦合布局,每一处物理实现都直接决定系统可靠性。48V平台因兼具安全性(<60V ELV)、复杂度(13–14串)与产业普及性,成为BMS工程实践的理想标本。本文聚焦真实电池包中的PCB级设计缺陷识别、关键参数现场验证(如±5mV采样误差、5mΩ导通内阻)、UART协议

weixin_29191081的博客 236

【FOC无刷电机控制】六步换向、FOC,STM32cubemx从零开始搭建BLDC六步换相代码、FOC代码(基于霍尔传感器)

FOC、六步换相,无刷电机控制

xifan的博客 3万+

【Spring】——Spring生命周期

❤️❤️❤️前面我们讲完了Spring中有关Bean的读和取,我们还没有还好去了解了解Bean对象,这篇 就是对Bean的深入学习。

冷兮雪的博客 1万+

Open Dynamics Engine(ODE)物理引擎基础教程(I)——特点介绍

下一教程 Open Dynamics Engine(ODE)物理引擎基础教程(II)——相关概念 (在这一教程中将学习刚体、关节、碰撞的概念在ODE中的特点) 本文结构引言介绍特点使用ODE总结 引言 本文翻译自ODE官方教程英文版,有些地方增加了自己的理解。这一节介绍ODE的相关概念。 基础教程英文原版链接【http://ode.org/wiki/index.php?title=Manua...

腿足机器人领域 1677

深入剖析Spring(三)——Bean的生命周期

对于普通的Java对象,当new的时候创建对象,当它没有任何引用的时候被垃圾回收机制回收。而由Spring IoC容器托管的对象,它们的生命周期完全由容器控制。Spring中每个Bean的生命周期如下:1. 实例化Bean对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。

大闲人柴毛毛 5040

推荐一个直接用于项目开发的PID库!很好用,很稳定

关注、星标公众号,不错过精彩内容大家好,我是小麦。最近有朋友问到有没有现成的C语言PID库。当然有了!现在我就准备给大家安利一下了。一般同学会去某度上搜,看到各种各样版本的PID示例,或者...

一名热爱技术的工程师的博客。分享技术干货,记录美好生活。永远相信美好的事情即将发生。 9025

使用Verilog实现QR分解——嵌入式 [设计与代码]

通过Verilog的硬件描述语言,我们可以将QR分解算法实现为硬件电路,并在嵌入式系统中高效地运行。本文将介绍如何使用Verilog设计并实现QR分解算法,该算法用于将一个矩阵分解为正交矩阵Q和上三角矩阵R。具体而言,QR分解通过对矩阵的列进行正交化处理,得到正交矩阵Q,并将对应的正交化结果存储在上三角矩阵R中。该算法通过将矩阵分解为两个部分,正交矩阵Q和上三角矩阵R,实现了对矩阵的分解和变换。模块,该模块接收待分解矩阵A,并输出正交矩阵Q和上三角矩阵R。下面给出了使用Verilog实现QR分解的源代码。

CodeMaven的博客 621

【SSM - Spring篇02】IOC容器 - 控制反转和依赖注入详解,案例实现(注解方式)

控制反转和依赖注入 控制反转(Inversion of Control,IoC)是一个比较抽象的概念,是Spring框架的核心,用来消减计算机程序的耦合问题。 依赖注入(Dependency Injection,DI)是IoC的另外一种说法,只是从不同的角度,描述相同的概念。 控制反转是一种通过描述(在Spring中可以是XML或注解)并通过第三方去产生或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入。 依赖注入是Spring容器将被依赖对象赋值给调用者的成员变量,相当

Java小皮孩 6619

【第三方互联】12、支付宝(Alipay)授权第三方登录

我们创建了支付宝开放平台的网页&移动应用,审核通过后,我们需要拿到appid,支付宝公钥,私钥进项开发 一、添加应用信息至项目环境中 我们保存了 appid、应用私钥、支付宝公钥、支付宝回调地址等信息,这里的公钥为支付宝开放平台为我们生成的“支付宝公钥” 二、引入 Maven 依赖 <!-- 支付宝SDK --> <dependency> <g.........

JACKAL 21万+

如何使用注解管理Spring Bean的生命周期呢?

使用注解管理Spring Bean的生命周期的方法分享

qq_25073223的博客 338

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Spring注解版之生命周期

1通过@Bean注解指定初始化和销毁时机 bean的生命周期 bean创建–初始化–销毁的过程 可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法 指定初始化和销毁方法 在@Bean注解里指定init方法和destroy方法 构造(对象创建) 单实例:在容器启动时创建 多实例:每次获取时创建 初始化:对象创建时 销毁: 单实例:关闭容器时 多实例:...

qq_30163473的博客 370

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Spring的 Bean 注解和生命周期

Spring 的 bean 注解声明 使用 @Autowired 注解自动装配 bean,要想把类标识成可用于 @Autowired 注解自动装配的 bean 的类,采用以下注解可实现: @Component :通用的注解,可标注任意类为 Spring 组件。如果一个 Bean 不知道属于哪个层,可以使用 @Component 注解标注。 @Repository : 对应持久...

happyJared 301

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【Spring注解】生命周期

Spring注解 生命周期初始化和销毁调用时机自定义初始化和销毁的方式@Bean指定初始化和销毁方法initializingBean和DisposableBean接口@PostConstruct 和@PreDestroyBeanPostProcessor 后置处理器BeanPostProcessor原理Spring底层对BeanPostProcessor的使用 bean的生命周期:bean创建–>初始化–>销毁的过程 在Spring中由容器管理bean的生命周期,我们可以自定义初始化和销毁方法

flora 1016

Spring注解之生命周期

1.什么是生命周期 生命周期是通常是指一个bean在ioc 容器中的一系过程。 bean被创建(某个类的构造方法被初始化) bean的初始化这个bean初始化方法(init()\ afterPropertiesSet() \ @PostConstruct标注的方法)被调用。 bean的销毁这个bean销毁方法(destroy() \ @PreDestroy标注的方法)被调用 2.生命周期...

只会一点Java 2591

spring 注解开发之生命周期

spring 注解开发之生命周期 bean的生命周期:bean创建---初始化----销毁的过程 bean的生命周期是由容器管理; 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法 构造(对象创建) 单实例:在容器启动的时候创建对象 多实例:在每次获取的时候创建对象 自定义初始化...

Mokyskury的博客 371

Spring Boot 纯注解实现Bean的生命周期

最近在准备面试,有关Bean的生命周期被问到了,下来巩固一下,之前都是针对Spring在回答Bean的各项注意事项,由于现在Spring Boot用的更多,因此找了一些如何用纯注解实现的方式。 首先是Bean的完整加载流程: 接下来是代码实现(已经按照顺序): @Component public class Person implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean

Dennis学习小站 564

Spring生命周期注解之@PostConstruct,@PreDestroy

目录 1. 注解说明 2. 调用过程 3. 调用分析 1. 注解说明 @PostConstruct,@PreDestroy是Java规范JSR-250引入的注解,定义了对象的创建和销毁工作,同一期规范中还有注解@Resource,Spring也支持了这些注解; 在Spring中,@PostConstruct,@PreDestroy注解的解析是通过BeanPostProcessor实现的...

luojinbai的专栏 4543

Spring注解开发_Bean生命周期及执行过程

Spring注解开发_Bean生命周期及执行过程 浅尝Spring注解开发,基于Spring 4.3.12 包含Bean生命周期、自定义初始化方法、Debug BeanPostProcessor执行过程及在Spring底层中的应用 Spring注解开发_自定义注册组件、属性赋值、自动装配 Spring注解开发_Bean生命周期及执行过程 Bean生命周期 了解Bean的生命周期,就可以在Bean声明周期的不同阶段进行自定义的操作,满足更复杂的需求。简单的将Bean生命周期分为三个阶段:Bean创建、初

hey_wei_ran的博客 1658

Spring的常用注解和生命周期

角色与功能@Component@Service和都是用来定义Bean的,但它们各自代表不同的层次和职责。依赖注入方式@Autowired和@Resource的用法不同,前者是按类型注入,后者是按名称注入;@Inject也是按类型,但更符合标准。切面通知的不同@Before@After和@Around分别代表不同的切面执行时机。Web相关注解及其简化版本用于处理Web请求,而和则是提取请求信息的工具。这些注解共同构成了Spring框架的灵活性和强大功能,允许开发者以声明性方式管理应用程序的各个方面。

weixin_44719499的博客 951

Spring注解之Bean生命周期

简记Bean生命周期(xml方式与注解方式)什么是Bean1. xml方式1.1. 在 Spring中有两种bean: 普通Bean 和 工厂Bean1.1.1. FactoryBean举例代码1.2. Bean作用域1.2.1. 举例代码1.3. bean生命周期以及bean的后置处理器1.3.1. 举例代码:2. 注解方式2.1. IOC容器管理Bean生命周期2.2. 构造对象2.3. 初始化2.4. 销毁2.5. 指定初始化和销毁方法2.5.1 @Bean(initMethod = "init",d

weixin_42893756的博客 1002

Spring注解版-生命周期

Bean的生命周期指的是组件在容器中实例化到初始化到销毁的整个过程; 实例化: 单实例: 在容器启动时实例化对象; 多实例: 在每次获取的时候实例化对象 初始化: 对象实例化完成, 并赋值好, 调用初始化方法; 销毁: 单实例: 在容器关闭时调用销毁方法销毁bean;多实例: 容器不会管理这个bean的销毁方法, 所以需要手动调用bean的销毁方法; 声明周期管理方法: 通过@Bean的属性initMethod指定初始化方法;通过@Bean的属性destroyMethod 指定销毁方法 @Confi

Feirana的博客 360

Spring的注解开发以及spring容器中bean的生命周期

1、开启注解的包扫描 2、常用的注解@Repository dao层 @Component 组件通用 @Service service层 @Controller 控制层这四个注解的功能其实是一样的,名字不同只是为了区分层次结构,在实际开发中完全可以都使用@Component。3、作用域注解@scope("singleton") @scope("prototype")......

weixin_43723296的博客 282
上一篇: tomcat8原理分析
下一篇: Spring注解(赋值相关)
Art&Code
博客等级 码龄7年 77粉丝 554原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值