AOP: Aspect Oriented Programming -- 织入
工作原理为采用代理对象, 继承InvocationHandler, Struts2的Interceptor也是典型的AOP, 原理的sample:
package com.lohamce.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class LogInterceptor implements InvocationHandler{
private Object target;
public void beforeMethod(Method method){
System.out.println("["+method.getName()+" begins]");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
beforeMethod(method);
method.invoke(target, args);
return null;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
}
@Test
public void testProxy() throws Exception{
UserDao userDao = new UserDaoImpl();
LogInterceptor li = new LogInterceptor();
li.setTarget(userDao);
UserDao proxy = (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), li);
proxy.save(new User());
proxy.remove(new User());
}
在Spring中有2种方式配置AOP
1. Annotation, 使用AspectJ实现, AspectJ是AOP的框架, 实现需要加入aspectjweaver.jar和aspectjrt.jar
织入的语法比较麻烦, 使用的话,需要查文档
package com.lohamce.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component("logInterceptor")
public class LogInterceptor {
private Object target;
@Before("execution (public * com.lohamce.service.impl.*.*(..))")
public void beforeMethod(){
System.out.println("[Method begins]");
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
}
2. XML,比annotation更有优势,因为可以插拔,有可能切面类的逻辑是第三方的提供的.
<aop:config>
<aop:pointcut expression="execution (public * com.lohamce.service.impl.*.*(..))" id="servicePointcut"/>
<aop:aspect id="logAspect" ref="logInterceptor">
<aop:before method="beforeMethod" pointcut-ref="servicePointcut" />
</aop:aspect>
</aop:config>
Spring初始化之后,当执行到com.lohamce.service.impl下面的类方法时,判断是否符合表达式 (servicePointcut), 如果符合, 在执行此方法前调用logIntercetor的beforeMethod方法
<aop: advisor> 声明式的事务管理才处理