介绍
Spring Aop 主要是依靠JDK动态代理和CGLB代理的方式,其区别在于JDK动态代理需要被增强对象实现接口,CGLB代理则是创建子类继承被增强对象。
Spring的Aop通知一共有如下五种
- 前置通知
- 后置通知
- 异常通知
- 环绕通知
- 最终通知
方式一注解加xml文件
选择增强被增强的对象
public class User {
public String add(String name) throws Exception {
System.out.println("欢迎"+name+"的加入");
// throw new Exception();
return null;
}
}
public class UserProxy {
//前置通知
@Before(value="execution(* cn.wxknx.spring.aop.dao.User.add(..))")
public void Before(){
System.out.println("前置通知1");
}
}
增加xml配置
<bean id="User" class="cn.wxknx.spring.aop.dao.User"></bean>
<context:component-scan base-package="cn.wxknx.spring.aop.aopanno"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
增加注解
@Component
@Aspect
@Order(1)//数值越小优先级越高
public class UserProxy {
//前置通知
@Before(value="execution(* cn.wxknx.spring.aop.dao.User.add(..))")
public void Before(){
System.out.println("前置通知1");
}
//后置通知
@AfterReturning(value="execution(* cn.wxknx.spring.aop.dao.User.add(..))")
public void afterReturning(){
System.out.println("后置返回通知1");
}
@After(value="execution(* cn.wxknx.spring.aop.dao.User.add(..))")
public void After(){
System.out.println("最终通知1");
}
@AfterThrowing(value="execution(* cn.wxknx.spring.aop.dao.User.add(..))")
public void afterThrowing(){
System.out.println("异常通知1");
}
@Around(value="execution(* cn.wxknx.spring.aop.dao.User.add(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕通知切入点前1");
proceedingJoinPoint.proceed();
System.out.println("环绕通知切入点后1");
}
}
测试
ApplicationContext ctx =new ClassPathXmlApplicationContext("spring-cfg.xml");
User user=(User) ctx.getBean("User");
user.add("张三");
如果是同一个切入点可以利用一下进行简化
@Pointcut("execution(* cn.wxknx.spring.aop.dao.User.add(..))")
public void pointDemo(){
}
@Before("pointDemo()")
public void before(){
System.out.println("前置通知");
}
第二 全xml配置
创建被增强和增强类
public class User {
public String add(String name) throws Exception {
System.out.println("欢迎"+name+"的加入");
return null;
}
}
public class UserProxy {
public void beforeABC(){
System.out.println("前置通知");
}
...
}
xml配置
<bean id="myUser" class="cn.wxknx.spring.aop.annotation.dao.MyUser"></bean>
<bean id="userProxy" class="cn.wxknx.spring.aop.annotation.annotationAop.UserProxy"></bean>
<!-- 配置aop增强-->
<aop:config>
<!-- 切入点-->
<aop:pointcut id="p" expression="execution(* cn.wxknx.spring.aop.annotation.dao.MyUser.delete(..))"/>
<!-- 配置切面-->
<aop:aspect ref="userProxy">
<aop:before method="beforeABC" pointcut-ref="p"></aop:before>
<aop:after method="afterABC" pointcut-ref="p"></aop:after>
<aop:after-returning method="afterReturning" pointcut-ref="p"></aop:after-returning>
<aop:around method="round" pointcut-ref="p"></aop:around>
<aop:after-throwing method="throwing" pointcut-ref="p"></aop:after-throwing>
</aop:aspect>
</aop:config>
测试
ApplicationContext ctx=new ClassPathXmlApplicationContext("cn\\wxknx\\spring\\aop\\annotation\\spring-cfg.xml");
MyUser user = ctx.getBean("myUser", MyUser.class);
user.delete("张三");
第三 全注解
创建被增强和增强类
public class MyUser {
public String add(String name) throws Exception {
System.out.println("欢迎"+name+"的加入");
return null;
}
}
public class SamePointCut {
@Pointcut("execution(* cn.wxknx.spring.aop.annotation.dao.MyUser.add(..))")
public void pointDemo(){
}
@Before("pointDemo()")
public void before(){
System.out.println("前置通知");
}
...
}
配置类
@Configuration
@ComponentScan(basePackages = {"cn.wxknx.spring.aop.annotation"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopConfig {
}
增加注解
@Component
@Aspect
public class SamePointCut {
@Pointcut("execution(* cn.wxknx.spring.aop.annotation.dao.MyUser.add(..))")
public void pointDemo(){
}
...
}
@Component(value="User")
public class MyUser {
public String add(String name) throws Exception {
System.out.println("欢迎"+name+"的加入");
return null;
}
}
测试
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AopConfig.class);
MyUser user = ctx.getBean("User", MyUser.class);
user.add("张三");