1、AOP是指将重复性的代码织入流程,开发者只关心业务部分,典型的例子是jdbc数据库连接,也就是说将重复的代码放在通知中
2、术语
1)连接点:可理解为目标对象的函数
2)切点:可理解为对哪个类下的哪个函数进行拦截
3)通知:约定流程下的函数,有前置通知,后置通知,环绕通知,事后返回通知,异常通知。其中环绕通知是级别最高的。
4)切面:可理解为拦截器,里面有切点和通知
5)织入:通过动态代理技术,为目标对象生成代码对象。
3、实现代码
1)连接点
实体类
package com.example.bootaop.pojo;
import lombok.Data;
@Data
public class User {
private Integer id;
private String userName;
private String note;
}
定义接口
package com.example.bootaop.service;
import com.example.bootaop.pojo.User;
public interface UserService {
void printUser(User user);
}
定义实现类
package com.example.bootaop.service.Impl;
import com.example.bootaop.pojo.User;
import com.example.bootaop.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Override
public void printUser(User user) {
if (user==null){
throw new RuntimeException("参数为空!");
}
System.out.println(user.getId());
System.out.println(user.getUserName());
System.out.println(user.getNote());
}
}
2)切面(包含切点和通知部分)
package com.example.bootaop.aspect;
import com.example.bootaop.aspect.validator.Impl.UserValidatorImpl;
import com.example.bootaop.aspect.validator.UserValidator;
import com.example.bootaop.pojo.User;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* 切面
*/
@Aspect
@Component
public class MyAspect {
/**
* 引入接口增强
*/
@DeclareParents(value = "com.example.bootaop.service.Impl.UserServiceImpl", defaultImpl = UserValidatorImpl.class)
public UserValidator userValidator;
/**
* 切点
*/
@Pointcut("execution(* com.example.bootaop.service.Impl.UserServiceImpl.printUser(..))")
public void pointCut(){
}
@Before("pointCut() && args(user)")
public void before(JoinPoint point, User user){
Object[] args=point.getArgs();
System.out.println(user);
System.out.println(args[0]);
System.out.println("before......");
}
@After("pointCut()")
public void after(){
System.out.println("after......");
}
@AfterReturning("pointCut()")
public void afterReturning(){
System.out.println("afterReturning.......");
}
@AfterThrowing("pointCut()")
public void afterThrowing(){
System.out.println("afterThrowing.......");
}
@Around("pointCut()")
public void around(ProceedingJoinPoint jp) throws Throwable{
System.out.println("around before......");
//回调原有目标对象方法
jp.proceed();
System.out.println("around after......");
}
}
3)引入接口增强
接口
package com.example.bootaop.aspect.validator;
import com.example.bootaop.pojo.User;
public interface UserValidator {
boolean validate(User user);
}
接口实现类
package com.example.bootaop.aspect.validator.Impl;
import com.example.bootaop.aspect.validator.UserValidator;
import com.example.bootaop.pojo.User;
public class UserValidatorImpl implements UserValidator {
public boolean validate(User user){
System.out.println("引入增强");
return user!=null;
}
}
4)控制器测试代码
@Autowired
private UserService userService;
@GetMapping(value = "/test")
public String test(){
User user = new User();
user.setId(12);
user.setUserName("testy");
user.setNote("xxxxxx");
UserValidator userValidator=(UserValidator)userService;
if(userValidator.validate(user)){
userService.printUser(user);
}
// userService.printUser(user);
return "OK";
}