1.是什么?
面向切面编程,横切关注点被模块化为特殊的类,这些类被称为切面
2.为什么?
解耦;让一组类共享相同的行为(在OOP开发模式中只能通过继承和实现接口来实现,单继承,阻碍了更多的行为添加到一组类中)
3.怎么用?
3.1声明切面 @Aspect
3.2定义建言(advice) @After @Before @Around
4.demo
4.1在spring工程中创建如下几个文件
4.1.1编写拦截规则的注解
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
Stringname();
}
4.1.2编写一个使用注解的被拦截类
import org.springframework.stereotype.Service;
@Service
public class DemoAnnotationService {
@Action(name ="注解式拦截的add操作")
public void add() {
System.out.println("我就是那个需要被拦截的方法!!!");
}
}
4.1.3编写切面
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class LogAspect {
@Pointcut("@annotation(com.dxj.springboot.springbootdemo.Action)")
public void annotationPointCut(){};
@Before("annotationPointCut()")
public void before(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
Action action = method.getAnnotation(Action.class);
System.out.println("我是Before!注解式拦截" + action.name());
}
@After("annotationPointCut()")
public void after(JoinPointjoinPoint){
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
Action action = method.getAnnotation(Action.class);
System.out.println("我是AFTER!注解式拦截" + action.name());
}
}
4.1.4 配置类
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
**@ComponentScan("com.xxx.springboot.springbootdemo")**
**@EnableAspectJAutoProxy**
public class AopConfig {
}
4.1.5 运行
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@SpringBootApplication
public class SpringbootDemoApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =new AnnotationConfigApplicationContext(AopConfig.class);
DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
demoAnnotationService.add();
context.close();
}
}
4.1.6结果
4.1.7解释
以上的代码实际上就是一个利用反射实现的日志记录,@Action注释的方法定义成了一个切点,@After注解声明了一个建言,并使用了这个切点,那么被@Action注释的方法都是切点,执行完后(After)都会执行这个建言。
【参考】
《Java EE开发的颠覆者 Spring Boot实战》