public class User {
private Integer id;
private String username;
private String note; public User(Integer id, String username, String note) {
this.id = id;
this.username = username;
this.note = note;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getNote() {
return note;
} public void setNote(String note) {
this.note = note;
} @Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", note='" + note + '\'' +
'}';
}
}

接口:

//@Component接口不用添加注入到容器,因为接口不能进行实例化
public interface UserService {
public void printUser(User user);
public void manyAspect();
}

实现类:

@Component
public class UserServiceImpl implements UserService { /**
* 这个方法将作为我们的AOP的接入点
* @param user
*/
@Override
public void printUser(User user) {
if (user.getUsername() == null){
throw new RuntimeException("检查用户参数是否为空。。。。");
}
System.out.println("id = "+ user.getId());
System.out.println("username = " + user.getUsername());
System.out.println("note = " + user.getNote());
} @Override
public void manyAspect() {
System.out.println("manyAspect------");
}
}
/**
* 定义切面
* @Aspect声明切面
*/
//@Aspect
public class MyAspect { //避免我们重复写一个表达式,引入了切入点概念PointCut,描述哪些类的哪些方法需要开启AOP编程。
@Pointcut("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.printUser(..))")
public void pointCut(){
} @Before("pointCut()")
public void before(){
System.out.println("before......");
} @After("pointCut()")
public void after(){
System.out.println("after......");
} @AfterReturning("pointCut()")
public void afterreturning(){
System.out.println("agterreturning.....");
} @AfterThrowing("pointCut()")
public void afterthrowing(){
System.out.println("afterthrowing.....");
} /**
* ProceedingJoinPoint类型参数,给参数的对象中有个方法proceed方法。回调原来的方法。
* @Around注解会取代原有目标的方法的通知。不进行回调得时候,方法是空的。
* @param joinPoint
* @throws Throwable
*/
@Around("pointCut()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("around before....");
//可以在这里打断点去查看joinPoint的内容
joinPoint.proceed();
System.out.println("around after....");
}
/**
* http://localhost:8080/aop/userprint?id=22&username=quan&note=huolala
* 有回调:
* around before...
* before......
* id = 22
* username = quan
* note = huolala
* agterreturning.....
* after......
* around after....
* ################
* 没回调:
* around before....
* around after....
*/ /**
* @DeclareParents作用:引入新的类来增强服务,
* value:指向你要增强功能的目标对象,这里要增强对象为UserServiceImpl对象
* defaultImpl:引入增强功能的类,UserValidatorImpl提供校验用户是否为空的
*/
@DeclareParents(value = "quan.springframework.springbootaop.aopdone.UserServiceImpl",defaultImpl = UserValidatorImpl.class)
public UserValidator userValidator; @DeclareParents(value = "quan.springframework.springbootaop.aopdone.UserServiceImpl",defaultImpl = UserValidatorIdImpl.class)
public UserValidatorId userValidatorId; /**
* 通知获取参数,
* && args(user)并将目标对象方法-名称为user的参数传递进来。
* @param joinPoint
* @param user
* 注意:
* JoinPoint类型的参数对于非环绕通知而言的参数。spring AOP自动传递到通知中
* 环绕通知自动你传递的参数为ProceedingJoinPoint类型的参数。
*/
@Before("pointCut() && args(user)")
public void beforeParam(JoinPoint joinPoint,User user){
Object[] args = joinPoint.getArgs();
System.out.println(args);
System.out.println("before param....");
} // @Before("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.printUser(..))")
// public void before(){
// System.out.println("before......");
// }
//
// @After("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.printUser(..))")
// public void after(){
// System.out.println("after......");
// }
//
// @AfterReturning("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.printUser(..))")
// public void afterreturning(){
// System.out.println("agterreturning.....");
// }
//
// @AfterThrowing("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.printUser(..))")
// public void afterthrowing(){
// System.out.println("afterthrowing.....");
// } /**
* execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.printUser(..))
* execution:表示执行时,拦截里面的正则匹配方法;
* *:表示任意返回类型的方法
* quan.springframework.springbootaop.aopdone.UserServiceImpl:指定目标对象的全限定类名
* printUser:指定目标对象的方法
* (**):表示任意参数进行匹配
*/ }

多切面:

/**
* 第一个切面
*/
@Order(3)
@Aspect
public class MyManyAop { @Pointcut("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.manyAspect(..))")
public void manyAspects(){
} @Before("manyAspects()")
public void before(){
System.out.println("MymanyAop1---before......");
} @After("manyAspects()")
public void after(){
System.out.println("MymanyAop1---after......");
} @AfterReturning("manyAspects()")
public void afterreturning(){
System.out.println("MymanyAop1---agterreturning.....");
} }
/**
* 第二个切面
*/
@Order(2)
@Aspect
public class MyManyAop2 { @Pointcut("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.manyAspect(..))")
public void manyAspects(){
} @Before("manyAspects()")
public void before(){
System.out.println("MymanyAop2---before......");
} @After("manyAspects()")
public void after(){
System.out.println("MymanyAop2---after......");
} @AfterReturning("manyAspects()")
public void afterreturning(){
System.out.println("MymanyAop2---agterreturning.....");
}
}
/**
* 第三个切面
*/
@Order(1)
@Aspect
public class MyManyAop3 { @Pointcut("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.manyAspect(..))")
public void manyAspects(){
} @Before("manyAspects()")
public void before(){
System.out.println("MymanyAop3---before......");
} @After("manyAspects()")
public void after(){
System.out.println("MymanyAop3---after......");
} @AfterReturning("manyAspects()")
public void afterreturning(){
System.out.println("MymanyAop3---agterreturning.....");
}
}

各个切面需要加入到容器当中:

@Configuration
public class AopConfiguration { /**
* 需要将切面加入到容器当中才能被织入
* @return
*/
@Bean("myAspect")
public MyAspect initMyAspect(){
return new MyAspect();
} /**
* 第一个切面
*/
@Bean("myManyAop")
public MyManyAop initMyManyAspect1(){
return new MyManyAop();
} /**
* 第二个切面
*/
@Bean("myManyAop2")
public MyManyAop2 initMyManyAspect2(){
return new MyManyAop2();
} /**
* 第三个切面
*/
@Bean("myManyAop3")
public MyManyAop3 initMyManyAspect3(){
return new MyManyAop3();
} }

通过类增强的:

/**
* 新建一个增强接口
*/
public interface UserValidator { public boolean validate(User user);
} /**
* 增强接口实现类
*/
public class UserValidatorImpl implements UserValidator { @Override
public boolean validate(User user) {
System.out.println("add validate");
return user.getUsername() != null;
}
}
public interface UserValidatorId {
public boolean idBigTWY(User user);
} public class UserValidatorIdImpl implements UserValidatorId{ @Override
public boolean idBigTWY(User user) {
System.out.println("UserValidatorId");
return user.getId() > 20;
}
}

什么是织入:

/**
* 织入:生成动态代理对象并且将切面和目标对象方法编织称为约定流程的过程
* Spring推荐的方式是接口+实现类的模式。
* spring支持JDK和CGLIB;
* JDK要求被代理对象必须拥有接口。
* CGLIB不做要求
* spring处理规则:当需要使用AOP的类拥有接口时,会以JDK动态代理运行,否则已CGLIB运行
* 注意:
* Spring 5.x 中 AOP 默认依旧使用 JDK 动态代理。
* SpringBoot 2.x 开始,为了解决使用 JDK 动态代理可能导致的类型转化异常而默认使用 CGLIB。
*/
@Controller
@RequestMapping("/aop")
public class AopController { @Autowired
UserService userService; @RequestMapping("/userprint")
@ResponseBody
public User pringUser(Integer id,String username,String note){
User user = new User(id,username,note);
userService.printUser(user);
return user;
}
/**
* request:
*http://localhost:8080/aop/userprint?id=22&username=quan&note=huolala
* result:
* before......
* id = 22
* username = quan
* note = huolala
* agterreturning.....
* after......
*/ @RequestMapping("/quote")
@ResponseBody
public User validateAndPrint(int id,String username,String note){
User user = new User(id,username,note);
//强制转换为UserValidator。
UserValidator userValidator = (UserValidator)userService;
if ( userValidator.validate(user) ){//判断是否为空user.username是否为空
userService.printUser(user);
} UserValidatorId userValidatorId = (UserValidatorId)userService;
if (userValidatorId.idBigTWY(user)){
System.out.println(user.getId());
}
return user;
} @RequestMapping("/many")
@ResponseBody
public String many(){
userService.manyAspect();
return "many aspect";
}
/**
* 顺序不一样的。
* MymanyAop1---before......
* MymanyAop2---before......
* MymanyAop3---before......
* manyAspect------
* MymanyAop3---agterreturning.....
* MymanyAop3---after......
* MymanyAop2---agterreturning.....
* MymanyAop2---after......
* MymanyAop1---agterreturning.....
* MymanyAop1---after......
*/ /**
* 加入Order:
* MymanyAop3---before......
* MymanyAop2---before......
* MymanyAop1---before......
* manyAspect------
* MymanyAop1---agterreturning.....
* MymanyAop1---after......
* MymanyAop2---agterreturning.....
* MymanyAop2---after......
* MymanyAop3---agterreturning.....
* MymanyAop3---after......
* 前置通知before都是从小到大运行,而后置通知和返回通知都是从大到小运行
* 典型的责任链模式顺序。
*/
}

最新文章

  1. 104-switch语句读法:
  2. thinkphp 介绍
  3. Java中将0x开头的十六进制字符串转换成十进制整数
  4. js 进度条,可实现结束和重新开始
  5. 让PowerShell用上Git
  6. BZOJ3680 : 吊打XXX
  7. Ehcache(2.9.x) - API Developer Guide, Transaction Support
  8. 03 将MDB文件在DATAGRID中显示
  9. dedecms模版制作活动的折叠菜单
  10. Code Review中应该关注的点
  11. 5.MyBaits调用存储过程
  12. JSP中文编码问题
  13. mysql left join 几个意思
  14. 记录python接口自动化测试--requests使用和基本方法封装(第一目)
  15. Rhino学习教程——1.5
  16. LDOOP设置关联后超出新起一页LinkNewPage
  17. vue的技巧代码
  18. vue2.0项目中 localhost改成ip地址访问
  19. 【webdriver自动化】整理API框架(主要是关键字,具体例子在本地)
  20. Hive编程指南

热门文章

  1. pycharm创建模板
  2. 【C# .Net GC】sos.dll 混合模式调试(托管调试+本机)
  3. 【windows安全性 之访问控制】 访问控制 详细解说
  4. 【C# 基础概念】C# 4 dynamic - var, object, dynamic的区别以及dynamic的使用
  5. jq给手机号加密
  6. 修改Ehcache缓存中取到的值,缓存中的值也被修改了
  7. WPS:为什么无法页眉页脚同前节(同前节是灰的)
  8. 使用Python绘制彩色螺旋矩阵
  9. 【spring】事务底层的实现流程
  10. 【故障公告】龙卷风来袭:突增的并发请求,撑不住的CPU