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中