AOP学习(一)

1.简介

  AOp:面向切面编程,相对于OOP面向对象编程。

  Spring的AOP的存在目的是为了解耦。AOP可以让一切类共享相同的行为。在OOP中只能通过继承类或者实现接口,使代码的耦合度增强,且类继承只能为单继承,阻碍更多行为添加到一组类上,AOP弥补了OOP的不足。

  Spring支持AspectJ的注解式切面编程。

  (1)使用@Aspect声明是一个切面;

  (2)使用@After、@Before、@Around定义通知(Advice),可直接将拦截规则(切点)作为参数;

  (3)其中@After、@Before、@Around参数的拦截规则为切点(Pointcut),为了使切点复用,可使用@Pointcut 专门定义拦截规则,然后在@After、@Before、@Around的参数中调用;

  (4)其中符合条件的每一个被拦截处为连接点(JoinPoint)。

  下面示例将演示基于注解拦截和基于方法规则拦截两种方式,演示一种模拟记录操作的日志系统的实现。其中注解式拦截能够很好地控制要拦截的粒度和获得更丰富的信息,Spring本身在事务处理(@Transcational)和数据缓存(@Cacheable)等都使用此种形式的拦截。

2.示例

(1)新建springboot项目,在pom.xml文件中添加spring aop  以及支持AspectJ 依赖

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency> (2)注解拦截,编写拦截规则的注解
/**
* 自定义拦截规则注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
String name();
} (3)编写使用注解拦截的 业务类
/**
* 使用注解的被拦截类
*/
@Service
public class DemoAnnotationService { @Action(name="注解式拦截的add操作")
public void add(){}
}
(4)编写使用方法规则拦截的 业务类
/**
* 使用方法规则的被拦截类
*/
@Service
public class DemoMethodService {
public void add(){}
} (5)编写切面
/**
* 切面
*/
@Aspect//注解声明一个切面
@Component//让切面成为Spring容器管理的Bean
public class LoginAspect { //通过@Pointcut注解声明切点
@Pointcut("@annotation(com.wenhuang.springboot.aop.Action)")
public void annotationPointCut(){}; //通过@After 注解声明一个通知,并使用@Pointcut定义切点
@After("annotationPointCut()")
public void after(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method =signature.getMethod();
Action action =method.getDeclaredAnnotation(Action.class);
System.out.println("注解式拦截,"+ action.name());//通过反射获取注解上的属性
} //通过@Before 注解声明一个通知,直接使用拦截器规则作为参数
@Before("execution(* com.wenhuang.springboot.aop.service.DemoMethodService.*(..))")
public void before(JoinPoint joinPoint){
MethodSignature signature=(MethodSignature)joinPoint.getSignature();
Method method =signature.getMethod();
System.out.println("方法规则式拦截,"+method.getName());
}
}
(6)配置类
@Configuration
@ComponentScan("com.wenhuang.springboot.aop")
@EnableAspectJAutoProxy //使用该注解开启Spring对AspectJ代理的支持
public class AopConfig {
}
(7)运行
public class Main {
public static void main(String[] args){
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(AopConfig.class);
DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);
demoAnnotationService.add();
demoMethodService.add();
context.close();
}
} 结果如下

springBoot AOP学习(一)-LMLPHP

05-11 14:50