编程方式实现AOP
示例
- 定义Advice
public class LogMethodInterceptor implements MethodInterceptor{
private LogPrinter printer;
public LogMethodInterceptor(LogPrinter printer) {
this.printer = printer;
}
public LogMethodInterceptor() {
this.printer = new SysLogPrinter();
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
printer.printLog();
return invocation.proceed();
}
}
- 定义Advicor
public class AbstractLogAdvisorPostProcessor extends ProxyProcessorSupport implements BeanPostProcessor{
private static final long serialVersionUID = -6245858583504116328L;
protected Advisor advisor;
protected boolean beforeExistingAdvisors = false;
private final Map<Class<?>, Boolean> eligibleBeans = new ConcurrentHashMap<Class<?>, Boolean>(256);
public void setBeforeExistingAdvisors(boolean beforeExistingAdvisors) {
this.beforeExistingAdvisors = beforeExistingAdvisors;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof AopInfrastructureBean) {
// Ignore AOP infrastructure such as scoped proxies.
return bean;
}
if (bean instanceof Advised) {
Advised advised = (Advised) bean;
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
// Add our local Advisor to the existing proxy's Advisor chain...
if (this.beforeExistingAdvisors) {
advised.addAdvisor(0, this.advisor);
}
else {
advised.addAdvisor(this.advisor);
}
return bean;
}
}
if (isEligible(bean, beanName)) {
ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
if (!proxyFactory.isProxyTargetClass()) {
evaluateProxyInterfaces(bean.getClass(), proxyFactory);
}
proxyFactory.addAdvisor(this.advisor);
customizeProxyFactory(proxyFactory);
return proxyFactory.getProxy(getProxyClassLoader());
}
// No async proxy needed.
return bean;
}
protected boolean isEligible(Class<?> targetClass) {
Boolean eligible = this.eligibleBeans.get(targetClass);
if (eligible != null) {
return eligible;
}
eligible = AopUtils.canApply(this.advisor, targetClass);
this.eligibleBeans.put(targetClass, eligible);
return eligible;
}
protected boolean isEligible(Object bean, String beanName) {
return isEligible(bean.getClass());
}
protected ProxyFactory prepareProxyFactory(Object bean, String beanName) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
proxyFactory.setTarget(bean);
return proxyFactory;
}
protected void customizeProxyFactory(ProxyFactory proxyFactory) {
}
}
public class LogPostProcessor extends AbstractLogAdvisorPostProcessor implements InitializingBean {
private static final long serialVersionUID = 3188630240751916965L;
private Class<? extends Annotation> validatedAnnotationType = LoggerAnn.class;
private LogPrinter printer;
public LogPrinter getPrinter() {
return printer;
}
public void setPrinter(LogPrinter printer) {
this.printer = printer;
}
@Override
public void afterPropertiesSet() throws Exception {
// 创建Pointcut
Pointcut pointcut = new AnnotationMatchingPointcut(validatedAnnotationType,true);
// 传入Pointcut和Advice,创建Advisor
this.advisor = new DefaultPointcutAdvisor(pointcut, createLogAdvice(this.printer));
}
private LogMethodInterceptor createLogAdvice(LogPrinter printer) {
return printer == null ? new LogMethodInterceptor() : new LogMethodInterceptor(printer);
}
}
重要类图。
ProxyFactory
类图
ProxyFactory继承了ProxyCreatorSupport类,持有了AopProxyFactory,AdvisorChainFactory,
List。等
类 | 作用 |
---|---|
AopProxyFactory | 基于 AdvisedSupport 配置信息,生成AOP 代理对象.默认为“DefaultAopProxyFactory” |
AdvisorChainFactory | advisor链。默认实现为DefaultAdvisorChainFactory,只有一个方法,获取Advised满足条件的MethodInterceptor列表或DynamicInterceptionAdvice列表 |
Advisor | 持有AOP advice和pointcut |
ProxyConfig | 生成代理对象的配置元信息 |
Advice&Pointcut&Advisor
Adivce类图
Pointcut类图
Advisor类图
Advisor是设计的核心元素,起到承上启下的作用,连接着Advice和Pointcut。默认实现是:DefaultPointCutAdvisor。需要知道2个接口ClassFilter,MethodMatcher,通过方法名,就可以判定他们的作用了,主要用在"匹配"上。
ClassFilter,MethodMatcher
代码AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply():
获取可以匹配的增强器
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
在AOPUtil类中我们发现
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
if (!pc.getClassFilter().matches(targetClass)) {// 获取Pointcut中的ClassFilter对象进行匹配
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();// 获取Pointcut中的MethodMatcher对象进行匹配
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if ((introductionAwareMethodMatcher != null &&
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}