org.aspectj
aspectjweaver
1.9.4
<aop:config>……aop:config>
<aop:config>……aop:config>
<aop:config>
<aop:aspect ref="beanId">……aop:aspect>
<aop:aspect ref="beanId">……aop:aspect>
aop:config
<aop:config>
<aop:pointcut id="pointcutId" expression="……"/>
<aop:aspect>
<aop:pointcut id="pointcutId" expression="……"/>
aop:aspect>
aop:config
⚫ execution :匹配执行指定方法
⚫ args :匹配带有指定参数类型的方法
⚫ within :……
⚫ this :……
⚫ target :……
⚫ @within :……
⚫ @target :……
⚫ @args :……
⚫ @annotation :……
⚫ bean :……
⚫ reference pointcut :……
<aop:config>
<aop:pointcut id="pt1" expression="execution(* *(..))"/>
<aop:aspect ref="myAdvice">
<aop:pointcut id="pt2" expression="execution(* *(..))"/>
<aop:before method="logAdvice" pointcut-ref="pt1"/>
<aop:before method="logAdvice" pointcut-ref="pt2"/>
<aop:before method="logAdvice" pointcut="execution(* *(..))"/>
aop:aspect>
aop:config>
<aop:aspect ref="adviceId">
<aop:before method="methodName" pointcut="……"/>
aop:aspect>
<aop:aspect ref="adviceId">
<aop:after method="methodName" pointcut="……"/>
aop:aspect>
<aop:aspect ref="adviceId">
<aop:after-returning method="methodName" pointcut="……"/>
aop:aspect>
<aop:aspect ref="adviceId">
<aop:after-throwing method="methodName" pointcut="……"/>
aop:aspect>
<aop:aspect ref="adviceId">
<aop:around method="methodName" pointcut="……"/>
aop:aspect>
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object ret = pjp.proceed();
return ret;
}
注意:当同一个切入点配置了多个通知时,通知会存在运行的先后顺序,该顺序以通知配置的顺序为准
public void before(JoinPoint jp) throws Throwable {
Object[] args = jp.getArgs();
}
public int save() {
System.out.println("user service running...");
return 100;
}
<aop:aspect ref="myAdvice">
<aop:pointcut id="pt3" expression="execution(* *(..)) "/>
<aop:after-returning method="afterReturning" pointcut-ref="pt3" returning="ret"/>
</aop:aspect>
public void afterReturning(Object ret) {
System.out.println(ret);
}
public int save() {
System.out.println("user service running...");
return 100;
}
<aop:aspect ref="myAdvice">
<aop:pointcut id="pt2" expression="execution(* *(..)) "/>
<aop:around method="around" pointcut-ref="pt2" />
</aop:aspect>
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object ret = pjp.proceed();
return ret;
}
public void save() {
System.out.println("user service running...");
int i = 1/0;
}
<aop:aspect ref="myAdvice">
<aop:pointcut id="pt4" expression="execution(* *(..)) "/>
<aop:after-throwing method="afterThrowing" pointcut-ref="pt4" throwing="t"/>
</aop:aspect>
public void afterThrowing(Throwable t){
System.out.println(t.getMessage());
}
public void save() {
System.out.println("user service running...");
int i = 1/0;
}
<aop:aspect ref="myAdvice">
<aop:pointcut id="pt4" expression="execution(* *(..)) "/>
<aop:around method="around" pointcut-ref="pt4" />
</aop:aspect>
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object ret = pjp.proceed(); //对此处调用进行try……catch……捕获异常,或抛出异常
return ret;
}
@Aspect
public class AopAdvice {
}
@Pointcut("execution(* *(..))")
public void pt() {
}
@Before("pt()")
public void before(){
}
@After("pt()")
public void after(){
}
@AfterReturning(value="pt()",returning = "ret")
public void afterReturning(Object ret) {
}
@AfterThrowing(value="pt()",throwing = "t")
public void afterThrowing(Throwable t){
}
@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object ret = pjp.proceed();
eturn ret;
}
@Configuration
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy
public class SpringConfig {
}
public class RunTimeMonitorAdvice {
//拦截所有的业务层接口中查询操作的执行
@Pointcut("execution(* com.itheima.service.*Service.find*(..))")
public void pt(){}
@Around("pt()")
public Object runtimeMonitor(ProceedingJoinPoint pjp) throws Throwable {
//获取执行签名信息
Signature signature = pjp.getSignature();
//通过签名获取执行类型(接口名)
String targetClass = signature.getDeclaringTypeName();
//通过签名获取执行操作名称(方法名)
String targetMethod = signature.getName();
//获取操作前系统时间beginTime
long beginTime = System.currentTimeMillis();
Object ret = pjp.proceed(pjp.getArgs());
//获取操作后系统时间endTime
long endTime = System.currentTimeMillis();
System.out.println(targetClass+" 中 "+targetMethod+" 运行时长 "+(endTime-beginTime)+"ms");
return ret;
}
}
public class UserServiceDecorator implements UserService{
private UserService userService;
public UserServiceDecorator(UserService userService) {
this.userService = userService;
}
public void save() {
//原始调用
userService.save();
//增强功能(后置)
System.out.println("刮大白");
}
}
/*
JDKProxy
*/
/*
重要的三个参数:
AccountService.class.getClassLoader() 获取被代理对象的类加载器
AccountService.class.getInterfaces() 获取被代理对象所有的接口
new InvocationHandler(){} 对原始方法执行进行拦截并增强
*/
public static AccountService creatAccountServiceJDKProxy(final AccountService accountService){
AccountService proxy = (AccountService) Proxy.newProxyInstance(AccountService.class.getClassLoader(), AccountService.class.getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object ret = method.invoke(accountService, args);
System.out.println("方法增强1...");
return ret;
}
});
return proxy;
}
/*
Cglib动态代理于JDK动态代理的区别
JDK动态代理:
实现了被代理的接口
Cglib动态代理:
继承了被代理的实现类
*/
public class TestCglibProxyAndJDKProxy {
/*
CglibPrixy
*/
public static AccountServiceImpl creatAccountServiceImplCglibProxy(Class clazz){
//创建Enhancer对象,(在内存中动态创建了一个类的字节码)
Enhancer enhancer = new Enhancer();
//理解为继承AccountServiceImpl
enhancer.setSuperclass(clazz);
MethodInterceptor mi = new MethodInterceptor() {
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//原来AccountServiceImpl内部的所有方法(包括了HashCode以及toString方法)
Object o1 = methodProxy.invokeSuper(o, objects);
//自己想增强的方法
if ("save".equals(method.getName())){
System.out.println("方法增强1..");
}
return o1;
}
};
enhancer.setCallback(mi);
return (AccountServiceImpl) enhancer.create();
}
<!--XMP配置AOP-->
<aop:config proxy-target-class="false">
</aop:config>
<!--注解配置AOP-->
<aop:aspectj-autoproxy proxy-target-class="false"/>
//注解驱动
@EnableAspectJAutoProxy(proxyTargetClass = true)