03-SpringBoot——Spring基础-AOP
【博文目录>>>】
【项目源码>>>】
【AOP】
AOP :面向切面编程,相对于OOP 面向对象编程。
Spring 的AOP 的存在白的是为了解耦。AOP 可以让一组类共享相同的行为。在OOP 中只能通过继承类和实现接口,来使代码的耦合度增强,且类继承只能为单继承,阻碍更多行为添加到一组类上, AOP 弥补了OOP 的不足。
Spring 支持AspectJ 的注解式切面编程。
(1)使用@Aspect 声明是一个切面。
(2)使用@After、@Before 、@Around 定义通知( advice ),可直接将拦截规则(切点)作为参数。
【功能实现】
package com.example.spring.framework.aop;
import java.lang.annotation.*;
/**
* 注解本身是没有功能的,就和xml 一样。注解和xml都是一种元数据(解释数据的数据),
* 注解的功能来自用这个注解的地方。
* ElementType.METHOD:说明此注解使用在方法上
* RetentionPolicy.RUNTIME:在运行期保留
* Documented:可用于生成java文档
*
* Author: 王俊超
* Date: 2017-07-10 22:26
* All Rights Reserved !!!
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
String name();
}
package com.example.spring.framework.aop;
import org.springframework.stereotype.Service;
/**
* Author: 王俊超
* Date: 2017-07-10 22:27
* All Rights Reserved !!!
*/
@Service
public class DemoAnnotationService {
@Action(name = "注解式拦截的add操作")
public void add(){}
}
package com.example.spring.framework.aop;
import org.springframework.stereotype.Service;
/**
* Author: 王俊超
* Date: 2017-07-10 22:29
* All Rights Reserved !!!
*/
@Service
public class DemoMethodService {
public void add(){}
}
package com.example.spring.framework.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* Author: 王俊超
* Date: 2017-07-10 22:30
* All Rights Reserved !!!
*/
@Aspect // 通过@Aspect 注解声明一个切面。
@Component // @Component让此切面成为Spring 容器管理的Beano
public class LogAspect {
// 通过@PointCut 注解声明切点
@Pointcut("@annotation(com.example.spring.framework.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.getAnnotation(Action.class);
System.out.println("注解式拦截 " + action.name()); //5
}
// 通过@Before注解声明一个建言,此建言直接使用拦截规则作为参数。
@Before("execution(* com.example.spring.framework.aop.DemoMethodService.*(..))")
public void before(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("方法规则式拦截,"+method.getName());
}
}
package com.example.spring.framework.aop;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* Author: 王俊超
* Date: 2017-07-10 22:29
* All Rights Reserved !!!
*/
@Configuration
@ComponentScan("com.example.spring.framework.aop")
@EnableAspectJAutoProxy
public class AopConfig {
}
package com.example.spring.framework.aop;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Author: 王俊超
* Date: 2017-07-10 22:22
* All Rights Reserved !!!
*/
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();
}
}