一、点睛
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本身在事务处理(@Transactional)和数据缓存(@Cacheable等)上面都是用此种形式的注解。
二、示例
(1)、添加Spring aop支持和AspectJ依赖
<!--spring aop支持-->
<!--spring aop支持-->
<dependency>
<groupId>org.springframework <groupId>
<groupId>org.springframework <groupId>
`````
</dependency>
<!--aspectj支持-->
<dependency>
<groupId>org.aspectj<groupId>
<artifactId> aspectjrt</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>org.aspectj<groupId>
<artifactId> aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>
(2)、编写拦截规则的注解
(2)、编写拦截规则的注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action{
String name();
}
public @interface Action{
String name();
}
代码解释:
这里讲一下注解 注解本身是没有功能的,他和xml一样都是一种元数据,元数据就是解释数据的数据,这就是所谓的配置,注解的功能来自用这个注解的地方。
(3)、编写使用注解的被拦截类
@Service
这里讲一下注解 注解本身是没有功能的,他和xml一样都是一种元数据,元数据就是解释数据的数据,这就是所谓的配置,注解的功能来自用这个注解的地方。
(3)、编写使用注解的被拦截类
@Service
public class DemoAnnotationService{
@Action (name="注解式拦截的add操作")
public void add(){};
}
(4)、编写使用方法规则被拦截类
@Service
public class DemoMethodService{
public void add(){};
}
(5)、编写切面
@Aspect
@Component
public class LogAspect{
@Pointcut("") //(2)操作的路径
public void annotationPointCut(){};
@Action (name="注解式拦截的add操作")
public void add(){};
}
(4)、编写使用方法规则被拦截类
@Service
public class DemoMethodService{
public void add(){};
}
(5)、编写切面
@Aspect
@Component
public class LogAspect{
@Pointcut("") //(2)操作的路径
public void annotationPointCut(){};
@After ("annotationPointCut()")
public void after(JoinPoint joinPoint){
MethodSignature sinature=(MethodSignature )joinPoint.getSignature();
Method method =signature.getMethod();
Action action method .get Annotation(Action.class);
System.out.println("注解式拦截"+action.name());
}
@Before("execution(*
//service的路径.*()
)")
public void before (JoinPoint joinpoint ){
MethodSignature signature =( MethodSignature) joinPoint.getSignature();
Method method= signature.getMethod();
System.out.println("方法规则式拦截"+method.getName())
}
}
MethodSignature sinature=(MethodSignature )joinPoint.getSignature();
Method method =signature.getMethod();
Action action method .get Annotation(Action.class);
System.out.println("注解式拦截"+action.name());
}
@Before("execution(*
//service的路径.*()
)")
public void before (JoinPoint joinpoint ){
MethodSignature signature =( MethodSignature) joinPoint.getSignature();
Method method= signature.getMethod();
System.out.println("方法规则式拦截"+method.getName())
}
}
代码解释
1、通过@Aspect注解声明一个切面
2、通过@Component让此切面成为Spring容器管理的一个Bean;
3、通过@PointCut注解声明切点;
4、通过@After 注解声明一个建言,并使用@PointCut定义的切点;
5、通过反射可以得到注解上的属性,然后做日志相关的操作,下面的相同;
6、通过@Before注解声明一个建言,此建言直接使用拦截规则作为参数;
(6)、配置类
@Configuration
@ComponentScan(“”)//需要扫面的包
@EnableAspectJAutoProxy
public class AopConfig{}
代码解释:
1、使用@EnableAspectJAutoProxy注解开启Spring 对AspectJ的支持
(7)运行
和Java运行时代码一致;