spring框架现在可以说是java后端标配了,说到spring的特点,很多可能张口就能说出来,AOP和IOC,即面向切面和控制反转,但是具体是什么样可能很多人就不清楚了,笔者也是实现了一段时间后才慢慢了解的。刚开始的时候看了很多AOP的例子但是都是似懂非懂,后来在代码里真正遇到了然后问题一个个轮着去查才了解一些。这里讲一下什么是AOP。
举个例子,比如在学校要求运动打卡,开始前签到打卡,结束后签退打卡,但是我们真正应该关心的是运动本身,而不是打卡。如果不使用AOP应该怎么实现呢
void signIn() {
System.out.println("签到打卡");
}
void signOff() {
System.out.println("签退打卡");
}
//跑步
void run() {
signIn();
System.out.println("跑步");
signOff();
}
就是这样,每次跑步前签到,跑完后签退,但是如果又加了一项篮球运动呢,最直接的办法是加一个方法
void playBasketball() {
signIn();
System.out.println("打篮球");
signOff();
}
可是如果又加了打排球打羽毛球等等呢,每次都在方法里调用signIn和signOff吗,这样代码耦合度太高而且一不小心可能忘记签到。这个时候就要用到AOP了。
@Aspect //表示该类是一个切面
public class Audience{
/*
* @Pointcut 定义一个切点
* execution 表示在方法执行时触发
* "*" 任意返回类型
* com.student.Sports 对应的类
* ".*" 任意方法
* (..) 任意参数
*/
@Pointcut("execution(* com.student.Sports.*(..))")
public void point() {
//该方法体为空用来定义切点
}
//运动前执行
@Beofore("point")
public void signIn() {
System.out.println("签到打卡");
}
//运动后执行
@After("point")
public void signOff() {
System.out.println("签退打卡");
}
}
这个类表示执行com.student.Sport类下的任意方法前会调用signIn方法,执行完后会调用singOff方法,这样一来就降低了耦合度,而且再添加运动项目的话只要在com.student.Sport类下加方法就行了。
上面的方法AOP也可以这么写
@Aspect //表示该类是一个切面
public class Audience{
//运动前执行
@Beofore("execution(* com.student.Sports.*(..))")
public void signIn() {
System.out.println("签到打卡");
}
//运动后执行
@After("execution(* com.student.Sports.*(..))")
public void signOff() {
System.out.println("签退打卡");
}
}
需要注意的是如果只是这样的话切面是不会生效的,还需要进行配置,以下是javaConfig中启动方式
@Configuration
@EnableAspectJAutoProxy // 启动AspectJ自动代理
@ComponentScan
public class ConcerConfig {
//声明Audience bean
@Bean
public Audience audience() {
return new Audience();
}
}
网友评论