Spring扩展接口

  • InstantiationAwareBeanPostProcessor 是 Spring 框架提供的一个扩展接口,通过实现 InstantiationAwareBeanPostProcessor 接口,并重写其中的方法,可以在 Spring 容器实例化和初始化 bean 的各个阶段进行自定义处理,从而灵活地对 bean 进行定制化的操作,主要功能如下:
    1. 实例化前置处理(Before Instantiation):在 Spring 容器实例化 bean 之前,可以通过这个接口来自定义 bean 的实例化方式。可以在此处进行一些特殊的准备工作,比如使用自定义的实例化逻辑或者切入点的选择。

    2. 实例化后置处理(After Instantiation):在 Spring 容器实例化 bean 之后,可以通过这个接口对实例化后的 bean 进行处理。可以在此处做一些初始化的操作,比如对属性进行赋值、调用初始化方法等。

    3. 属性设置前置处理(Before Property Set):在 Spring 容器对 bean 的属性进行设置之前,可以通过这个接口来自定义属性的设置方式。可以在此处对属性进行修改或者校验操作。

    4. 属性设置后置处理(After Property Set):在 Spring 容器对 bean 的属性进行设置之后,可以通过这个接口对属性设置后的 bean 进行处理。可以在此处做一些属性设置后的额外操作。

    5. 初始化前置处理(Before Initialization):在 Spring 容器对 bean 进行初始化之前,可以通过这个接口来自定义初始化的方式。可以在此处添加一些额外的初始化逻辑。

    6. 初始化后置处理(After Initialization):在 Spring 容器对 bean 进行初始化之后,可以通过这个接口对初始化后的 bean 进行处理。可以在此处做一些初始化后的额外操作。

public class OpenInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor{

    /**
     * 只用到了实例化前的方法
     * @param beanClass
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        //创建任何一个bean对象之前,都会自动调用这个方法,但是我们只对使用了自定义注解的类才创建代理对象,没有使用的直接返回null
        if(!beanClass.isAnnotationPresent(CustomProxy.class)){
            return null;
        }
        log.info("正在为:{}生成代理对象,被代理的类为:{}",beanName,beanClass.getName());
        //动态代理里面需要实现的方法,采用jdk动态代理
        //实例化每一个bean之前都来判断一下是否有自定义注解,如果有的话就创建代理对象并返回
        Object object = ProxyFactory.createProxy(beanClass);
        return object;
    }
}
  • ApplicationContextAware是Spring框架提供的一个特殊的回调接口,能够轻松感知并在Spring中获取应用上下文(Spring容器),进而访问容器中的其他Bean和资源,是Spring框架中的关键接口之一,在ApplicationContextAware接口中定义了一个setApplicationContext方法,当类实现了该接口之后,Spring IoC容器会自动调用该方法并将当前的ApplicationContext注入到所实现的setApplicationContext方法中,这样就可以在该类中使用Spring的应用上下文了,进而可以获取容器中的其他Bean、资源、配置信息等。

 

  • 工作机制:
    • Bean创建: 当Spring容器根据配置信息创建一个Bean实例时,它会检查这个Bean是否实现了任何Aware接口(包括ApplicationContextAware)。
    • Aware接口处理: 如果Bean实现了Aware接口,Spring容器会调用相应的set*方法,注入相应的依赖,对于ApplicationContextAware,容器会调用setApplicationContext方法。

    • 依赖注入: 在调用setApplicationContext方法时,Spring容器会将当前的ApplicationContext对象注入到Bean中,这个注入过程是通过Java反射机制实现的。

    • Bean后处理: 在Bean的所有属性被设置之后,Spring容器会调用Bean的后处理器(如果配置了的话),进行额外的初始化工作,对于实现了InitializingBean接口的Bean,还会调用其afterPropertiesSet方法。

    • 使用ApplicationContext: 一旦Bean被初始化并注入了ApplicationContext,它就可以使用这个上下文来执行各种操作,比如获取其他Bean、访问资源、读取配置等。

public class SpringContextUtil implements ApplicationContextAware, DisposableBean {

    private static ApplicationContext applicationContext = null;

    /**
     * 取得存储在静态变量中的ApplicationContext.
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 根据名字从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
     */
    public static <T> T getBean(String name) {
        assertContextInjected();
        return (T) applicationContext.getBean(name);
    }

    /**
     * 根据类型从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
     */
    public static <T> T getBean(Class<T> requiredType){
        assertContextInjected();
        return applicationContext.getBean(requiredType);
    }

    /**
     * 检查ApplicationContext不为空.
     */
    private static void assertContextInjected() {
        Validate.validState(applicationContext != null,
                "applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder.");
    }

    /**
     * 实现ApplicationContextAware接口, 注入Context到静态变量中,容器启动时框架会自动调用这个方法
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("注入ApplicationContext到SpringContextHolder:{}"+applicationContext);
        if (SpringContextUtil.applicationContext != null) {
            log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:"
                    + SpringContextUtil.applicationContext);
        }
        SpringContextUtil.applicationContext = applicationContext;
    }

    /**
     * 清除SpringContextHolder中的ApplicationContext为Null.
     */
    public static void clearHolder() {
        log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
        applicationContext = null;
    }


    /**
     * 实现DisposableBean接口, 在Context关闭时清理静态变量.
     */
    @Override
    public void destroy() throws Exception {
        SpringContextUtil.clearHolder();
    }
}

 

posted @ 2024-09-29 14:50  complexlong  阅读(58)  评论(0)    收藏  举报