利用spring扩展点代理bean的简单示例

BeanPostProcessor扩展点有两个方法:
1、在bean属性装配完成,执行完各种Aware之后,InitializingBean和init-method方法之前调用,返回的对象将替换原来的bean
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
2、InitializingBean和init-method方法执行之后调用,返回的对象将替换原来的bean,可以完成一些代理之类的工作
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

利用这个扩展点的postProcessAfterInitialization方法,可以完成对指定bean的代理

public class TimerFilter4Spring implements BeanPostProcessor {
	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	private boolean isProxy = false;
	private boolean canUseCglib = false;
	private List<String> beanNames;
	private List<String> classNames;

	private List<Pattern> beanNamePattern = new ArrayList<Pattern>();
	private List<Class<?>> classs = new ArrayList<Class<?>>();

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

	@SuppressWarnings("rawtypes")
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (isProxy) {
			if (this.containClass(bean) && this.containBeanName(beanName)) {
				if (bean.getClass().isInterface()) {
					Class[] interfaces = bean.getClass().getInterfaces();
					this.logger.info("TimerFilter4Spring(" + beanName + ") add to jdk proxy!");
					return Proxy.newProxyInstance(bean.getClass().getClassLoader(), interfaces,
							new TimerFilterInvocationHandler(bean, beanName));
				} else if (canUseCglib) {
					Enhancer enhancer = new Enhancer();
					enhancer.setSuperclass(bean.getClass());
					enhancer.setCallback(new TimerFilterInvocationHandler(bean, beanName));
					return enhancer.create();
				}
			}
		}
		return bean;

	}

	private boolean containBeanName(String beanName) {
		if (this.beanNamePattern != null && !this.beanNamePattern.isEmpty()) {
			for (Pattern pattern : this.beanNamePattern) {
				Matcher matcher = pattern.matcher(beanName);
				if (matcher.find()) {
					return true;
				}
			}
		} else {// 空表示全需要替换
			return true;
		}
		return false;
	}

	private boolean containClass(Object bean) {
		if (this.classs != null && !this.classs.isEmpty()) {
			for (Class<?> claz : this.classs) {
				if (claz.isInstance(bean)) {
					return true;
				}
			}
		} else {// 空表示全需要替换
			return true;
		}
		return false;
	}

	public void setIsProxy(boolean isProxy) {
		this.isProxy = isProxy;
	}

	public void setCanUseCglib(boolean canUseCglib) {
		this.canUseCglib = canUseCglib;
	}

	public void setBeanNames(List<String> beanNames) {
		this.beanNames = beanNames;
		if (this.beanNames != null && !this.beanNames.isEmpty()) {
			for (String str : this.beanNames) {
				str = StringUtils.trimToEmpty(str);
				if (StringUtils.isNotEmpty(str)) {
					try {
						this.beanNamePattern.add(Pattern.compile(str));
						this.logger.info(str + " add to TimerFilter4Spring.beanNamePattern success!");
					} catch (Exception e) {
						this.logger.error(str + " add to TimerFilter4Spring.beanNamePattern failure!", e);
					}
				}
			}
		}
	}

	public void setClassNames(List<String> classNames) {
		this.classNames = classNames;
		if (this.classNames != null && !this.classNames.isEmpty()) {
			for (String str : this.classNames) {
				str = StringUtils.trimToEmpty(str);
				if (StringUtils.isNotEmpty(str)) {
					try {
						this.classs.add(Class.forName(str));
						this.logger.info(str + " add to TimerFilter4Spring.classs success!");
					} catch (Exception e) {
						this.logger.error(str + " add to TimerFilter4Spring.classs failure!", e);
					}
				}
			}
		}
	}

	private class TimerFilterInvocationHandler implements InvocationHandler, MethodInterceptor {
		private Object target;

		// private String beanName;

		public TimerFilterInvocationHandler(Object target, String beanName) {
			this.target = target;
			// this.beanName = beanName;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			return this.doInvoke(this.target, args, method, null);
		}

		@Override
		public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
			return this.doInvoke(this.target, args, method, proxy);
		}

		private Object doInvoke(Object targetObj, Object[] args, Method method, MethodProxy proxy) throws Throwable {
			Throwable failed = null;
			Object result = null;
			try {
				// TODO 方法调用前
				if (proxy != null) {
					result = proxy.invoke(this.target, args);
				} else if (method != null) {
					result = method.invoke(this.target, args);
				}
				// TODO 方法调用后
			} catch (Throwable e) {
				failed = e;
				// TODO catch中
			} finally {
				System.out.println();
				// TODO finally中
			}

			if (failed != null) {
				throw failed;
			}
			return result;
		}

	}
}
 


上面这个过程是spring对xml配置方式使用aop的基本原理,当然spring对切入点、要代理的bean等的配置非常灵活,但是对xml配置方式的aop核心实现大概是这样,具体实现在org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator中


猜你喜欢

转载自lan-qie.iteye.com/blog/1763819