【问题标题】:Decorate or Intercept Spring @Autowired Bean装饰或拦截 Spring @Autowired Bean
【发布时间】:2021-12-11 01:16:06
【问题描述】:

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

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

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

【问题讨论】:

  • AOP 专门用于此目的,因此 AOP 更适合您的需要 ...
  • 你试过@PostConstruct吗?它解决了你的目的吗?

标签: spring spring-aop spring-bean spring-aspects


【解决方案1】:

我使用了这个替代方案而不是 AOP。我使用了 Spring 的 bean 前后处理器回调。下面是代码sn-p。

Application Context Provider,静态获取 Spring bean

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 后处理器,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;
    }
}

【讨论】:

    猜你喜欢
    • 2014-11-05
    • 2016-06-12
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-09
    • 1970-01-01
    相关资源
    最近更新 更多