spring AOP 程式設計式應用
一、spring AOP 和 AspectJ
spirng AOP: 是基於物件代理模式進行織入邏輯程式碼,但對於static和final方法上應用織入是無法做到的
AspectJ :其是一個獨立的在編輯期進行邏輯程式碼的織入框架,不受限於必須獲取代理
二、AOP織入
1. Advice、Pointcut、Advisor、ProxyFactory
Advice (通知)是AOP聯盟定義的一個介面,描述了連線點做什麼,為切面增強提供織入介面。編寫邏輯程式碼的基類
Pointcut (切點)決定Advice通知應該作用於哪個連線點。也就是說這些連線點集合(決定切入的方法)是通過Pointcut來決定的
Advisor (通知器)是對Advice和Pointcut的整合,作為IoC容器使用AOP的基礎設施。所有
ProxyFactory(生成代理物件的工廠類)可以讓我們通過程式設計式的方法實現spirng AOP功能在spring中有三個代理工廠類,除了上面提到的還有ProxyFactoryBean(宣告式應用)、AspectJProxyFactory(AspectJ應用),它們都繼承了ProxyCreatorSupport類
2. 應用演示
目標類,提供切入點
class TargetImpl {
public void print() {
System.out.println("this is target");
}
}
MethodInterceptor
MethodInterceptor是一個最基礎的繼承自->Interceptor->Advice的通知類。ProxyFactory生成bean代理有jdk proxy和Cglib兩種方式,但spirng把它們的回撥都統一封裝,回撥執行MethodInterceptor的invoke方法
具體封裝在了ReflectiveMethodInvocation裡,執行process來調起invoke
private static void basics() {
Advice advice = (MethodInterceptor) (invocation) -> {
System.out.println("enter advice->interceptor->methodInterceptor");
return invocation.proceed();
};
Pointcut pointcut = new Pointcut() {
@Override
public ClassFilter getClassFilter() {
return ClassFilter.TRUE;
}
@Override
public MethodMatcher getMethodMatcher() {
return MethodMatcher.TRUE;
}
};
Advisor advisor = new DefaultPointcutAdvisor(pointcut, advice);
ProxyFactory proxyFactory = new ProxyFactory(new TargetImpl());
proxyFactory.addAdvisor(advisor);
TargetImpl target = (TargetImpl) proxyFactory.getProxy();
target.print();
}
程式碼中出現的DefaultPointcutAdvisor是spirng提供的一個預設通知器
MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor
private static void before() {
Advice advice = new MethodBeforeAdviceInterceptor((method, objects, o) -> System.out.println("enter before advice"));
ProxyFactory proxyFactory = new ProxyFactory(new TargetImpl());
proxyFactory.addAdvice(advice);
TargetImpl target = (TargetImpl) proxyFactory.getProxy();
target.print();
}
private static void after() {
Advice advice = new AfterReturningAdviceInterceptor((rv, method, objects, o) -> System.out.println("enter after advice"));
ProxyFactory proxyFactory = new ProxyFactory(new TargetImpl());
proxyFactory.addAdvice(advice);
TargetImpl target = (TargetImpl) proxyFactory.getProxy();
target.print();
}
ProxyFactory雖然可以直接新增Advice,但這並不表示它不需要Ponitcut的實現。閱讀add方法原始碼可以看到它會生成一個預設的DefaultPointcutAdvisor新增在addAdvisor列表裡
@Override
public void addAdvice(int pos, Advice advice) throws AopConfigException {
Assert.notNull(advice, "Advice must not be null");
if (advice instanceof IntroductionInfo) {
// We don't need an IntroductionAdvisor for this kind of introduction:
// It's fully self-describing.
addAdvisor(pos, new DefaultIntroductionAdvisor(advice, (IntroductionInfo) advice));
}
else if (advice instanceof DynamicIntroductionAdvice) {
// We need an IntroductionAdvisor for this kind of introduction.
throw new AopConfigException("DynamicIntroductionAdvice may only be added as part of IntroductionAdvisor");
}
else {
addAdvisor(pos, new DefaultPointcutAdvisor(advice)); //建立預設Advisor
}
}
AspectJExpressionPointcut
spring通過AspectJExpressionPointcut來定義實現AspectJ中的切點語言
private static void aspectjBefore() {
TargetImpl target = new TargetImpl();
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution( * com.programmatic.springprogrammatic.TargetImpl.print(..) )");
Advice advice = new MethodBeforeAdviceInterceptor(new MethodBeforeAdvice() {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("enter before advice");
}
});
Advisor advisor = new DefaultPointcutAdvisor(pointcut, advice);
ProxyFactory proxyFactory = new ProxyFactory(target);
proxyFactory.addAdvisor(advisor);
TargetImpl proxyTarget = (TargetImpl) proxyFactory.getProxy();
proxyTarget.print();
}
結語
spring AOP可以說是通過兩個流程來實現對程式碼的切入和執行邏輯程式碼。
(1)通知器的裝配;spring AOP會把要切入點的位置和邏輯程式碼封裝為一個標準呼叫流程。
(2)生成代理類的時候注入通知器;這樣代理類在回撥方法時就會執行切入邏輯程式碼了。
程式設計式的實現spring AOP是最基礎的運用,它可以更好的使我們看到實現spring AOP裝配過程,為更好的理解spring AOP作為一個基礎篇
github地址:https://github.com/lotusfan/spring-programmatic ->ProxyFactoryTest
相關文章
- Spring AOP:面向切面程式設計的核心概念與實際應用Spring程式設計
- Spring 面向方面程式設計 AOPSpring程式設計
- Spring AOP——Spring 中面向切面程式設計Spring程式設計
- Spring之AOP面向切面程式設計Spring程式設計
- 聊聊Spring Reactor反應式程式設計SpringReact程式設計
- Spring系列:基於Spring-AOP和Spring-Aspects實現AOP切面程式設計Spring程式設計
- Spring Boot中面向方面程式設計 (AOP)教程Spring Boot程式設計
- Spring AOP(面向切面程式設計)是什麼?Spring程式設計
- Spring 5與Spring cloud的響應式程式設計之旅SpringCloud程式設計
- Spring 面向切面程式設計AOP 詳細講解Spring程式設計
- 手寫Spring---AOP面向切面程式設計(4)Spring程式設計
- 手寫Spring---AOP面向切面程式設計(3)Spring程式設計
- Util應用框架基礎(三) - 面向切面程式設計(AspectCore AOP)框架程式設計
- Day67 Spring AOP(面向切面程式設計) 和代理設計模式Spring程式設計設計模式
- AOP程式設計之AspectJ介紹及在Android中的應用程式設計Android
- 面向切片程式設計(AOP)應用的一些實際例子程式設計
- Spring Boot實戰系列(3)AOP面向切面程式設計Spring Boot程式設計
- 嵌入式Linux—Framebuffer應用程式設計Linux程式設計
- Spring Cloud Stream的函式式和響應式Reactive程式設計特點 - spring.ioSpringCloud函式React程式設計
- Spring AOP與AspectJ的對比及應用Spring
- Spring框架系列(4) - 深入淺出Spring核心之面向切面程式設計(AOP)Spring框架程式設計
- AOP(面向切面程式設計)程式設計
- AOP 面向切面程式設計程式設計
- Spring 程式設計式事務管理Spring程式設計
- 八、【spring】web應用安全設計SpringWeb
- Spring Boot 中的響應式程式設計和 WebFlux 入門Spring Boot程式設計WebUX
- Spring響應式Reactive程式設計的10個陷阱 -Jeroen RosenbergSpringReact程式設計ROS
- 響應式程式設計基礎教程:Spring Boot 與 Lettuce 整合程式設計Spring Boot
- 設計模式及其在spring中的應用(含程式碼)設計模式Spring
- 好程式設計師Java分享Spring框架之AOP的基本配置程式設計師JavaSpring框架
- Spring AOP高階應用與原始碼剖析Spring原始碼
- 設計模式之面向切面程式設計AOP設計模式程式設計
- 什麼是AOP程式設計?程式設計
- AOP程式設計實戰-AspectJ程式設計
- AOP--面向切面程式設計程式設計
- Spring Boot 2 (十):Spring Boot 中的響應式程式設計和 WebFlux 入門Spring Boot程式設計WebUX
- Unity應用架構設計(12)——AOP思想的實踐Unity應用架構
- Spring Cloud Stream應用與自定義RocketMQ Binder:程式設計模型SpringCloudMQ程式設計模型