Spring Bean 生命周期
本文最后更新于 941 天前,其中的信息可能已经有所发展或是发生改变。

Bean生命周期

InitializingBean & DisposableBean

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class User implements InitializingBean, DisposableBean {
    //执行顺序
    //1. Constructor构造函数
    public User() {
        System.err.println("Constructor");
    }
    //2. @PostConstruct注解
    @PostConstruct
    public void postConstruct() {
        System.err.println("postConstruct");
    }
    //3. InitializingBean接口
    @Override
    public void afterPropertiesSet() throws Exception {
        System.err.println("afterPropertiesSet");
    }
    //4. @Bean(initMethod = "myInit")
    public void myInit() {
        System.err.println("myInit");
    }
    //5. @PreDestroy注解
    @PreDestroy
    public void preDestroy() {
        System.err.println("preDestroy");
    }
    //6. DisposableBean接口
    @Override
    public void destroy() throws Exception {
        System.err.println("destroy");
    }
    //7. @Bean(destroyMethod = "myDestroy")
    public void myDestroy() {
        System.err.println("myDestroy");
    }
}

影响所有Bean

BeanPostProcessor & InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor接口继承于BeanPostProcessor接口。

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class CustomBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    //执行顺序
    //1. postProcessBeforeInstantiation
    //该方法执行时,Bean的Constructor构造函数还没执行
    @Override
    public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
        log.info("postProcessBeforeInstantiation");
        //返回null,调用doCreateBean()方法生成bean
        //返回bean,说明被aop代理,跳过后面的方法,直接执行postProcessAfterInitialization
        return null;
    }
    //2. postProcessAfterInstantiation
    //该方法执行前,Bean的Constructor构造函数已经执行
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        log.info("postProcessAfterInstantiation");
        //返回true,执行postProcessProperties
        //返回false,不执行postProcessProperties
        return true;
    }
    //3. postProcessProperties
    //该方法执行时,@Value注解的属性还没赋值
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        log.info("postProcessProperties");
        return pvs;
    }
    //4. postProcessBeforeInitialization
    //该方法执行前,@Value注解的属性已经赋值
    //该方法执行时,Bean的@PostConstruct、InitializingBean、@Bean(initMethod = "")的方法还没执行
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        log.info("postProcessBeforeInitialization");
        //返回null,调用doCreateBean()方法生成bean
        return bean;
    }
    //5. postProcessAfterInitialization
    //该方法执行前,Bean的@PostConstruct、InitializingBean、@Bean(initMethod = "")的方法已经执行
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        log.info("postProcessAfterInitialization");
        //返回bean,交给Spring IOC容器管理
        return bean;
    }
}

影响单个Bean

BeanNameAware

通过实现BeanNameAware接口可以获得Bean的名字(String)。

BeanClassLoaderAware

通过实现BeanClassLoaderAware接口可以获得Bean的类加载器(ClassLoader)。

BeanFactoryAware

通过实现BeanFactoryAware接口可以获得Bean工厂(BeanFactory)。

import lombok.Data;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.stereotype.Component;
@Component
public class UserBeanFactory implements BeanFactoryAware {
    @Data
    @Component
    public static class User {
        private String username = "admin";
        private Integer age = 20;
        private Boolean sex = true;
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        User user = beanFactory.getBean(User.class);//UserBeanFactory.User(username=admin, age=20, sex=true)
    }
}

ApplicationContextAware

通过实现ApplicationContextAware接口可以获得ApplicationContext上下文,ApplicationContext继承了ApplicationEventPublisherResourceLoaderMessageSource等接口,相当于同时实现了ApplicationEventPublisherAwareResourceLoaderAwareMessageSourceAware三个接口,详情请参考《Spring Boot 静态获取 Bean》

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class BeanUtils implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    //静态获取Bean
    public static  T getBean(Class clazz) {
        return applicationContext.getBean(clazz);
    }
}

EnvironmentAware

EmbeddedValueResolverAware

通过实现EmbeddedValueResolverAware接口可以获得Spring EL解析器(StringValueResolver),用户自定义注解需要支持spel表达式的时候可以使用。

BeanDefinition (Bean定义)

GenericBeanDefinition (Bean定义) & BeanDefinitionRegistry (Bean注册器)

import lombok.Data;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.stereotype.Component;
@Component
public class UserBeanFactory implements BeanFactoryAware {
    @Data
    public static class User {
        private String username = "admin";
        private Integer age = 20;
        private Boolean sex = true;
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) beanFactory;
        //构建Bean的元数据
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClass(User.class);
        MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
        propertyValues.add("username", "guanyu");
        propertyValues.add("age", 16);
        propertyValues.add("sex", false);
        //注册Bean到Spring IOC容器
        beanDefinitionRegistry.registerBeanDefinition("myUser", beanDefinition);
    }
//    @Resource
//    private User myUser;//UserBeanFactory.User(username=guanyu, age=16, sex=false)
}

BeanDefinitionBuilder (Bean定义构造器)

import lombok.Data;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.stereotype.Component;
@Component
public class UserBeanFactory implements BeanFactoryAware {
    @Data
    public static class User {
        private String username = "admin";
        private Integer age = 20;
        private Boolean sex = true;
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) beanFactory;
        //构建Bean的元数据,与GenericBeanDefinition作用相同
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
        //设置Bean的属性值
        beanDefinitionBuilder.addPropertyValue("username", "guanyu");
        beanDefinitionBuilder.addPropertyValue("age", 16);
        beanDefinitionBuilder.addPropertyValue("sex", false);
        //通过构造函数设置Bean的属性值,该方法内部是通过index索引确定入参顺序
//        beanDefinitionBuilder.addConstructorArgValue();
        //通过构造函数设置Bean的属性值(且该属性也被Spring管理)
//        beanDefinitionBuilder.addConstructorArgReference();
        //设置Bean的作用域,类似于@Scope注解的作用
        beanDefinitionBuilder.setScope(BeanDefinition.SCOPE_SINGLETON);//默认,单例
//        beanDefinitionBuilder.setScope(BeanDefinition.SCOPE_PROTOTYPE);//多例,每次getBean都new一个新Bean
        //设置Bean是否懒加载,默认是false,类似于@Lazy注解的作用
        beanDefinitionBuilder.setLazyInit(false);
        //设置Bean是否是默认Bean,默认是false,类似于@Primary注解的作用
        beanDefinitionBuilder.setPrimary(false);
        //设置Bean依赖的Bean名称,类似于@DependsOn注解的作用
//        beanDefinitionBuilder.addDependsOn();
        //设置Bean的init方法
//        beanDefinitionBuilder.setInitMethodName();
        //设置Bean的destroy方法
//        beanDefinitionBuilder.setDestroyMethodName();
        //设置Bean的自动装配规则,为已经实例化的对象装配属性
        beanDefinitionBuilder.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_NO);//默认,不自动注入
//        beanDefinitionBuilder.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);//使用Bean名称策略注入
//        beanDefinitionBuilder.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);//使用Bean类型策略注入
//        beanDefinitionBuilder.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);//使用Bean构造器策略注入
        //设置Bean的角色,可以不设置(没啥用),类似于@Role注解的作用
        beanDefinitionBuilder.setRole(BeanDefinition.ROLE_APPLICATION);//默认,表示这个Bean是用户自定义的Bean
//        beanDefinitionBuilder.setRole(BeanDefinition.ROLE_SUPPORT);//表示这个Bean是某个大型配置的支撑部分
//        beanDefinitionBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);//表示这个Bean是Spring内部的Bean
        //设置Bean是否是个抽象的BeanDefinition,默认false,如果是true,表明这个BeanDefinition只是用来给子BeanDefinition去继承的,Spring不会去尝试初始化这个Bean
        beanDefinitionBuilder.setAbstract(false);
        //检测依赖
        beanDefinitionBuilder.setDependencyCheck(AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);//默认,不进行依赖验证
//        beanDefinitionBuilder.setDependencyCheck(AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS);//对象引用的依赖性检查
//        beanDefinitionBuilder.setDependencyCheck(AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE);//简单属性(Enum,CharSequence,Number,Date,Class等)的依赖性检查
//        beanDefinitionBuilder.setDependencyCheck(AbstractBeanDefinition.DEPENDENCY_CHECK_ALL);//所有属性(对象引用和简单属性)的依赖性检查
        //获取BeanDefinition,且验证Bean定义
        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        //获取BeanDefinition,不验证Bean定义
//        AbstractBeanDefinition rawBeanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
        //注册Bean到Spring IOC容器
        beanDefinitionRegistry.registerBeanDefinition("myUser", beanDefinition);
    }
//    @Resource
//    private User myUser;//UserBeanFactory.User(username=guanyu, age=16, sex=false)
}

RootBeanDefinition & ChildBeanDefinition

Spring 2.5之后GenericBeanDefinition代替了RootBeanDefinitionChildBeanDefinition

import lombok.Data;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.*;
import org.springframework.stereotype.Component;
@Component
public class UserBeanFactory implements BeanFactoryAware {
    @Data
    public static class User {
        private String username = "admin";
        private Integer age = 20;
        private Boolean sex = true;
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) beanFactory;
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        rootBeanDefinition.setBeanClass(User.class);
        rootBeanDefinition.getPropertyValues().add("username", "guanyu");
        rootBeanDefinition.getPropertyValues().add("age", 16);
        rootBeanDefinition.getPropertyValues().add("sex", false);
        beanDefinitionRegistry.registerBeanDefinition("rootUser", rootBeanDefinition);
        //childUser的属性继承于rootUser
        ChildBeanDefinition childBeanDefinition = new ChildBeanDefinition("rootUser");
        beanDefinitionRegistry.registerBeanDefinition("childUser", childBeanDefinition);
        //与上述代码作用相同
//        GenericBeanDefinition rootBeanDefinition = new GenericBeanDefinition();
//        rootBeanDefinition.setBeanClass(User.class);
//        rootBeanDefinition.getPropertyValues().add("username", "guanyu");
//        rootBeanDefinition.getPropertyValues().add("age", 16);
//        rootBeanDefinition.getPropertyValues().add("sex", false);
//        beanDefinitionRegistry.registerBeanDefinition("rootUser", rootBeanDefinition);
//        GenericBeanDefinition childBeanDefinition = new GenericBeanDefinition();
//        childBeanDefinition.setParentName("rootUser");
//        beanDefinitionRegistry.registerBeanDefinition("childUser", childBeanDefinition);
    }
//    @Resource
//    private User rootUser;//UserBeanFactory.User(username=guanyu, age=16, sex=false)
//    @Resource
//    private User childUser;//UserBeanFactory.User(username=guanyu, age=16, sex=false)
}

ClassPathBeanDefinitionScanner (类扫描器) & BeanDefinitionRegistryPostProcessor (Bean注册器的后置处理器)

ClassPathBeanDefinitionScanner能够将指定包下的类通过一定规则(Filter)过滤后,包装成BeanDefinition并注册到Spring IOC容器中。

  1. 定义ClassPathBeanDefinitionScanner
    import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
    import org.springframework.beans.factory.config.BeanDefinitionHolder;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
    import org.springframework.core.type.AnnotationMetadata;
    import org.springframework.core.type.filter.AnnotationTypeFilter;
    import org.springframework.core.type.filter.AssignableTypeFilter;
    import java.lang.annotation.Annotation;
    import java.util.Set;
    public class MapperClassPathScanner extends ClassPathBeanDefinitionScanner {
        public MapperClassPathScanner(BeanDefinitionRegistry registry) {
            super(registry, false);//useDefaultFilters: false,表示跳过spring context等类的加载
        }
        /**
         * 因为ClassPathBeanDefinitionScanner的doScan方法被protected修饰,重写该方法可以获取BeanDefinitionHolder,
         * 通过BeanDefinitionHolder可以获取BeanDefinition,而BeanDefinition又能够对Bean进行属性赋值或动态代理等自定义操作
         */
        @Override
        public Set doScan(String... basePackages) {
            return super.doScan(basePackages);
        }
        /**
         * 通过Filter筛选的Class,后进入该方法判断是否应该被加载
         */
        @Override
        protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
            AnnotationMetadata metadata = beanDefinition.getMetadata();
    //        metadata.isInterface();//判断是否是接口
    //        metadata.isAbstract();//判断是否是抽象类
    //        metadata.isIndependent();//判断是否是类、抽象类、接口
    //        metadata.isConcrete();//既不是接口也不是抽象类
    //        metadata.isAnnotation();//判断是否是注解
    //        metadata.isFinal();//是否被final修饰
    //        metadata.hasSuperClass();//判断是否有父类
    //        metadata.hasEnclosingClass();//判断是否有内部类
    //        metadata.hasAnnotation();//判断类是否被指定注解修饰
    //        metadata.hasAnnotatedMethods();//判断类是否有指定注解修饰的方法
    //        metadata.hasMetaAnnotation();//判断类是否被指定元注解修饰的注解修饰
            return metadata.isInterface();
        }
        /**
         * 包含指定类、接口
         */
        public void includeClass(Class targetType) {
            addIncludeFilter(new AssignableTypeFilter(targetType));
        }
        /**
         * 包含指定注解
         */
        public void includeAnnotation(Class annotationType) {
            addIncludeFilter(new AnnotationTypeFilter(annotationType));
        }
        /**
         * 排除指定类、接口
         */
        public void excludeClass(Class targetType) {
            addExcludeFilter(new AssignableTypeFilter(targetType));
        }
        /**
         * 排除指定注解
         */
        public void excludeAnnotation(Class annotationType) {
            addExcludeFilter(new AnnotationTypeFilter(annotationType));
        }
    }
    
  2. 定义BeanDefinitionRegistryPostProcessor
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanDefinitionHolder;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.AbstractBeanDefinition;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
    import org.springframework.beans.factory.support.GenericBeanDefinition;
    import org.springframework.stereotype.Component;
    import java.util.Set;
    @Component
    public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor {
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
            MapperClassPathScanner mapperClassPathScanner = new MapperClassPathScanner(beanDefinitionRegistry);
            mapperClassPathScanner.includeClass(Mapper.class);
            Set beanDefinitionHolders = mapperClassPathScanner.doScan("com.tenbeggar.mapper");
            beanDefinitionHolders.forEach(e -> {
                GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) e.getBeanDefinition();
                genericBeanDefinition.setBeanClass(MapperFactoryBean.class);//此处传入FactoryBean接口实现,即可自定义动态代理规则
                genericBeanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_NO);//设置Bean自动装配规则,默认不自动装配
            });
        }
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        }
    }
    

ImportBeanDefinitionRegistrar (动态注册Bean)

Spring官方动态注册Bean也是使用ImportBeanDefinitionRegistrar接口,一般配合@Import注解使用。

  1. 声明一个被@Import修饰的注解
    import org.springframework.context.annotation.Import;
    import org.springframework.core.annotation.AliasFor;
    
    import java.lang.annotation.*;
    
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import({MapperScannerRegistrar.class})
    public @interface MapperScan {
    
        @AliasFor("basePackages")
        String[] value() default {};
    
        @AliasFor("value")
        String[] basePackages() default {};
    }
    
  2. 定义ImportBeanDefinitionRegistrar
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.support.BeanDefinitionBuilder;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
    import org.springframework.core.annotation.AnnotationAttributes;
    import org.springframework.core.type.AnnotationMetadata;
    import java.util.Map;
    public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            //获取@MapperScan注解属性的key-value
            Map annotationMap = importingClassMetadata.getAnnotationAttributes(MapperScan.class.getCanonicalName());
            //AnnotationAttributes是注解的工具类
            AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(annotationMap);
            if (annotationAttributes != null) {
                //获取@MapperScan注解basePackages属性的值
                String[] basePackages = annotationAttributes.getStringArray("basePackages");
                //构建Bean的元数据
                BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
                //用于描述一个Bean的角色,可以不设置
                //ROLE_APPLICATION:表示这个Bean是用户自定义的Bean
                //ROLE_SUPPORT:表示这个Bean是某个大型配置的支撑部分
                //ROLE_INFRASTRUCTURE:表示这个Bean是Spring内部的Bean
                beanDefinitionBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
                //注册Bean到Spring IOC容器
                registry.registerBeanDefinition(MapperScannerRegistrar.class.getTypeName(), beanDefinitionBuilder.getBeanDefinition());
            }
        }
    }
    

FactoryBean (Bean创建工厂)

FactoryBean配合BeanDefinition可以实现自定义动态代理。

  1. 定义一个接口
    public interface Mapper {}
  2. 默认接口实现
    public class DefaultMapper implements Mapper {}
  3. 实现FactoryBean,JDK动态代理
    import org.springframework.beans.factory.FactoryBean;
    import java.lang.reflect.Proxy;
    public class MapperFactoryBean implements FactoryBean {
        private Class interfaceClass;
        @Override
        public T getObject() throws Exception {
            //jdk动态代理
            return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[]{interfaceClass}, new MapperInvocationHandler());
        }
        @Override
        public Class getObjectType() {
            return interfaceClass;
        }
    }
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    public class MapperInvocationHandler implements InvocationHandler {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return method.invoke(new DefaultMapper(), args);
        }
    }
    
如果觉得本文对您有帮助,记得收藏哦~
上一篇
下一篇