SpringAOP 概念
连接点(join point):对应的是具体被拦截的对象,因为spring只能支持方法,所以被拦截的对象往往就是指特定的方法,例如我们提到UserServiceImpl 的 printUser方法就是一个连接点,AOP将通过动态代理几十把它织入对应的流程中。
切点(point cut):有时候,我们的切面不单单应用于单个方法,也可能是多个类的不同方法,这时,可以通过正则表达式和指示器的规则去定义,从而适配连接点,切点就是提供这样一个功能的概念。
通知(adive):就是按照约定的流程下的方法,分为前置通知(before adivce)、后置通知(after advice)、环绕通知(around advice)、事后返回通知(afterReturning advice)和异常通知(afterThrowing advice),它会根据预定织入流程中,需要弄明白它们在流程中的顺序和运行的条件。
目标对象(traget):即被代理对象。
引入(introduction):是指引入新的类和其方法,增强现有Bean的功能。
织入(weaving):它是通过一个动态代理技术,为原有服务对象生成代理对象,然后将与切点定义匹配的连接点拦截,并按约定定将各类通知织入约定流程的过程。
切面(aspect):是一个可以定义切点,各类通知和引入的内容,Sptring AOP 将通过它的信息来增强Bean的功能或者将对应的方法织入流程。
类型 | 描述 |
---|---|
arg() | 限定连接点方法参数 |
@args() | 通过连接点方法参数上的注解进行限定 |
execution() | 用于匹配是连接点的执行方法 |
this() | 限制连接点匹配AOP代码Bean引用为指定的类 |
target() | 目标对象(即被代理对象) |
@target() | 限制目标对象的配置了指定注解 |
within() | 限制连接点匹配指定的类型 |
@within() | 限定连接点带有匹配注解类型 |
@annotaion() | 限定带有指定注解的连接点 |
@Controller
@RequestMapping("/user")
public class UserController {
//注入用户服务
@Autowired
private UserService userService;
//定义请求
@RequestMapping(value = "/print",method = RequestMethod.GET)
//转化为JSON
@ResponseBody
public User printUser(Integer deptno, String dname, String dbSource) {
User user = new User();
user.setDeptno(deptno);
user.setDname(dname);
user.setDbSource(dbSource);
userService.printUser(null);//若user = null ,则执行afterthrowing 方法
return user;//切入点
}
}
public interface UserService {
void printUser(User user);
}
@Service
public class UserServiceImpl implements UserService {
@Override
public void printUser(User user) {
if(Objects.isNull(user)){
throw new RuntimeException("检查用户数据参数为空");
}
System.out.printf("id ="+user.getDeptno());
System.out.printf("dname ="+user.getDname());
System.out.println("dbsource ="+user.getDbSource());
}
}
public class User {
Integer deptno;
String dname;
String dbSource;
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getDbSource() {
return dbSource;
}
public void setDbSource(String dbSource) {
this.dbSource = dbSource;
}
}
@Aspect
public class MyAspect {
@Before(value = "execution(* com.tw.springtboot.aopPlus.service.impl.UserServiceImpl.printUser(..) )")
public void before() {
System.out.println("before……………………");
}
@After(value = "execution(* com.tw.springtboot.aopPlus.service.impl.UserServiceImpl.printUser(..) )")
public void after() {
System.out.println("after……………………");
}
@AfterReturning(value = "execution(* com.tw.springtboot.aopPlus.service.impl.UserServiceImpl.printUser(..) )")
public void afterReturning() {
System.out.println("afterReturning………………");
}
@AfterThrowing(value = "execution(* com.tw.springtboot.aopPlus.service.impl.UserServiceImpl.printUser(..) )")
public void afterThrowing() {
System.out.println("afterThrowing………………");
}
}
public class UserDao {
public int insertUser(Connection conn, User user) throws SQLException {
PreparedStatement preparedStatement = null;
try {
preparedStatement = conn.prepareStatement("insert into t_user(dname,db_source) values(?,?)");
preparedStatement.setString(1, user.getDname());
preparedStatement.setString(2, user.getDname());
return preparedStatement.executeUpdate();
} finally {
preparedStatement.close();
}
}
}
public class SpringtbootApplication {
//定义切面
@Bean(name = "myAspect")
public MyAspect initMyAspect(){
return new MyAspect();
}
// 启动切面
public static void main(String[] args) {
SpringApplication.run(SpringtbootApplication.class, args);
}
}