装饰或拦截 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 切入点。只是想知道有没有其他更好的选择可以像
一样使用
- 扩展
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
- 使用
BeanFactoryPostProcessor
或 BeanPostProcessor
。
- 使用
InstantiationAwareBeanPostProcessor
我已经使用了这个替代方案而不是 AOP。我已经使用了 Spring 的 bean pre & post 处理器回调。下面是代码片段。
Application 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;
}
}
我正在将旧的 Java EE 应用程序升级到基于 Spring 的解决方案。在旧的应用程序中,有自定义注释来创建代理注入代理 bean 并拦截方法调用 [Interceptor 类 implements MethodInterceptor
) or (implements InvocationHandler
),用于执行一些之前和执行后的东西。
我们已经用 Spring 标记接口(如 @Service、@Repository 等)替换了那些自定义注释,并且我们能够使用 @Autowire bean 实例。现在我的问题是如何拦截这些自动装配的 bean 以执行每个和 post 执行活动。我能想到的一种解决方案是使用 Spring AOP 并使用 @Around 切入点。只是想知道有没有其他更好的选择可以像
一样使用- 扩展
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
- 使用
BeanFactoryPostProcessor
或BeanPostProcessor
。 - 使用
InstantiationAwareBeanPostProcessor
我已经使用了这个替代方案而不是 AOP。我已经使用了 Spring 的 bean pre & post 处理器回调。下面是代码片段。
Application 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;
}
}