装饰或拦截 Spring @Autowired Bean

Decorate or Intercept Spring @Autowired Bean

我正在将旧的 Java EE 应用程序升级到基于 Spring 的解决方案。在旧的应用程序中,有自定义注释来创建代理注入代理 bean 并拦截方法调用 [Interceptor 类 implements MethodInterceptor) or (implements InvocationHandler),用于执行一些之前和执行后的东西。

我们已经用 Spring 标记接口(如 @Service、@Repository 等)替换了那些自定义注释,并且我们能够使用 @Autowire bean 实例。现在我的问题是如何拦截这些自动装配的 bean 以执行每个和 post 执行活动。我能想到的一种解决方案是使用 Spring AOP 并使用 @Around 切入点。只是想知道有没有其他更好的选择可以像

一样使用
  1. 扩展 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
  2. 使用 BeanFactoryPostProcessorBeanPostProcessor
  3. 使用InstantiationAwareBeanPostProcessor

我已经使用了这个替代方案而不是 AOP。我已经使用了 Spring 的 bean pre & post 处理器回调。下面是代码片段。

A​​pplication Context Provider,静态获取Spring beans

package com.appname.config;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @author dpoddar
 *
 */
@Component("applicationContextProvider")
public class ApplicationContextProvider implements ApplicationContextAware{
    private static ApplicationContext ctx = null;

    public static ApplicationContext getApplicationContext() {
        return ctx;
    }
    
    @Override
    @Autowired
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        ApplicationContextProvider.ctx = ctx;
    }
    
    /**
     * Returns the Spring managed bean instance of the given class type if it exists.
     * Returns null otherwise.
     * @param beanClass
     * @return
     */
    public static <T extends Object> T getBean(Class<T> beanClass) {
        return ctx.getBean(beanClass);
    }
    
    /**
     * Returns the Spring managed bean instance of the given class type if it exists.
     *  
     * @param <T>
     * @param name
     * @param beanClass
     * @return
     */
    public static <T extends Object> T getBean(String name,Class<T> beanClass) {
        return ctx.getBean(name,beanClass);
    }

}

Spring Bean Post Processor, InstantiationAwareBeanPostProcessor 添加前后初始化回调

package com.appname.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.SpringProxy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import com.appname.core.ExecutionContext;
import com.appname.core.di.FacadeService;
import com.appname.interceptors.BusinesServiceInterceptor;
import com.appname.interceptors.FacadeServiceInterceptor;
import com.appname.interceptors.RepositoryInterceptor;

import net.sf.cglib.proxy.Enhancer;

/**
 * @author dpoddar
 *
 */
@Component
public class AppSpringBeanPostProcessor extends AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor  {

    private static Logger logger = LoggerFactory.getLogger(AppSpringBeanPostProcessor.class);

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        Class<?> clazz = bean.getClass();
        AutowireCapableBeanFactory factory = ApplicationContextProvider.getApplicationContext().getAutowireCapableBeanFactory();

        if(clazz.isAnnotationPresent(FacadeService.class)) {
            //This is to instatiate InvocationHandler classes
            //return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new FacadeServiceInterceptor(bean));

            FacadeServiceInterceptor interceptor = new FacadeServiceInterceptor();
            Enhancer e = new Enhancer();
            e.setSuperclass(clazz);
            e.setInterfaces(new Class[]{SpringProxy.class});  /// Identification Spring-generated proxies
            e.setCallback(interceptor);
            Object o = e.create();
            factory.autowireBean( o ); //Autowire Bean dependecies to the newly created object
            return o;

        }else if(clazz.isAnnotationPresent(Service.class)) {
            BusinesServiceInterceptor interceptor = new BusinesServiceInterceptor();
            Enhancer e = new Enhancer();
            e.setSuperclass(clazz);
            e.setInterfaces(new Class[]{SpringProxy.class});
            e.setCallback(interceptor);
            Object o = e.create();
            factory.autowireBean( o );
            return o;
        }else if(clazz.isAnnotationPresent(Repository.class)) {
            ExecutionContext.newInstance();
            RepositoryInterceptor interceptor = new RepositoryInterceptor();
            Enhancer e = new Enhancer();
            e.setSuperclass(clazz);
            e.setInterfaces(new Class[]{SpringProxy.class});
            e.setCallback(interceptor);
            return e.create();
        }else {
            return bean;
        }

    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}