Spring AOP如何讓內部方法呼叫也發生代理
方法之間的呼叫直接使用的是原始物件,而非代理物件,因而內部呼叫不會產生代理
public class Waiter {
public void greetTo(String name) {
System.out.println("greet to :" + name);
}
public void serveTo(String name) {
System.out.println("serve to :" + name);
greetTo(name);
}
public class Seller { public void greetTo(String name) { System.out.println("greet to :" + name); } }
<bean id="waiter" class="com.demo.aop.Waiter"/> <bean id="seller" class="com.demo.aop.Seller"/> <bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" p:patterns=".*To.*"> <property name="advice"> <bean class="com.demo.aop.GreetingAdvice"/> </property> </bean> <!--自動根據advisor生成代理--> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" p:proxyTargetClass="true"/>
測試類:
@ContextConfiguration(locations = {"classpath:spring-context.xml"}) public class Test extends AbstractJUnit4SpringContextTests { @org.junit.Test public void test1() { Waiter waiter = (Waiter) applicationContext.getBean("waiter"); Seller seller = (Seller) applicationContext.getBean("seller"); System.out.println("---------------------------"); waiter.greetTo("John"); System.out.println("---------------------------"); waiter.serveTo("Ivern"); System.out.println("---------------------------"); seller.greetTo("Lili"); } }
結果:greet方法的內部呼叫沒有生成代理
修改:
/**
* 自動裝配代理物件介面
*/
public interface BeanSelfProxyAware {
void setBeanSelfProxy(Object proxyObj);
}
/**
* 自定義容器啟動外掛
*/
public interface SystemBootAddon extends Ordered {
void onReady();
}
/**
* 自定義管理器,當啟動完成時,對實現了BeanSelfProxyAware介面的bean注入proxyBean
*/
public class BeanSelfProxyMonter implements ApplicationContextAware, SystemBootAddon {
private ApplicationContext applicationContext;
public void onReady() {
Map<String, BeanSelfProxyAware> proxyAwares = applicationContext.getBeansOfType(BeanSelfProxyAware.class);
for (BeanSelfProxyAware proxyAware : proxyAwares.values()) {
proxyAware.setBeanSelfProxy(proxyAware);
}
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
/**
* 訊息監聽器,監聽Spring系統訊息
*/
public class SystemBootManager implements ApplicationListener<ContextRefreshedEvent> {
private List<SystemBootAddon> systemBootAddons;
private boolean hasRunOnce = false;
/**
* Spring自動注入所有的SystemBootAddon
*
* @param systemBootAddons
*/
@Autowired
public void setSystemBootAddons(List<SystemBootAddon> systemBootAddons) {
this.systemBootAddons = systemBootAddons;
}
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
if (!hasRunOnce) {
for (SystemBootAddon systemBootAddon :systemBootAddons) {
systemBootAddon.onReady();
}
hasRunOnce = true;
}
}
}
<bean id="waiter" class="com.demo.aop.Waiter"/>
<bean id="seller" class="com.demo.aop.Seller"/>
<bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
p:patterns=".*To.*">
<property name="advice">
<bean class="com.demo.aop.GreetingAdvice"/>
</property>
</bean>
<!--自動根據advisor生成代理-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
p:proxyTargetClass="true"/>
<!--註冊啟動器-->
<bean class="com.demo.aop.BeanSelfProxyMonter"/>
<!--註冊啟動載入器-->
<bean class="com.demo.aop.SystemBootManager"/>
public class Waiter implements BeanSelfProxyAware {
private Waiter waiterProxy;
public void setBeanSelfProxy(Object proxyObj) {
this.waiterProxy = (Waiter) proxyObj;
}
public void greetTo(String name) {
System.out.println("greet to :" + name);
}
public void serveTo(String name) {
System.out.println("serve to :" + name);
waiterProxy.greetTo(name);
}
}
最後的結果:
相關推薦
Spring AOP如何讓內部方法呼叫也發生代理
方法之間的呼叫直接使用的是原始物件,而非代理物件,因而內部呼叫不會產生代理public class Waiter { public void greetTo(String name) { System.out.println("greet to :"
spring AOP中自身方法呼叫無法應用代理解決辦法
如下例: public class MyServiceImpl implements MyService { public void do(){ //the transaction annotation won't work if yo
spring aop類內部呼叫不攔截原因及解決方案
spring對應java web開發的同學來說,都不陌生,其中事務@Transactional在service層更是常常使用。 1.aop類內部呼叫不攔截原因 細心的同學也許早就發現當service中的某個沒標註@Transactional的方法呼叫另一個標註
Spring AOP獲取攔截方法的參數名稱跟參數值
mon ogg try cat obj 超過 con 同時 point Spring AOP獲取攔截方法的參數名稱跟參數值 註意:這種方式需要JDK1.8版本支持 開始: 1.aop配置: <aop:aspectj-autoproxy expose-proxy
restTemplate踩過的坑-spring clound--cloud內部服務呼叫重試次數
轉載自 https://www.cnblogs.com/jimw/p/9037542.html 現在公司專案基本都從臃腫的專案轉換成微服務的方向轉換,因此也從中使用了spring clound的一些元件,在此過程中就遇到了restTemplate的坑。 起初,是直接注入RestTe
Spring Aop 修改目標方法引數和返回值
首先使用spring-aop需要在spring的配置檔案中假如 一、新建註解 @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented
Spring,為內部方法新起一個事務,此處應有坑
事務的作用,使我們操作能夠連貫起來。而spring則是提供了一個更簡單的方法,只要使用 @Transactional 一個註解,就可以保證操作的連貫性了。 普通用法,稍後再說,這裡要說的是: 在最外面的方法中,有一個@Transactional 的註解,當有丟擲異常時
Spring傳播行為內部方法不起作用
在使用Spring的註解事務時候,我們發現內部方法宣告的事務不起作用,而是決定於外部方法註解的事務。到底是真不起作用,還是我們Spring的事務註解機制理解錯了,導致誤用了。下面我們看兩個例子: 測試類: package com.aop; import org.spr
解決@Transactional事務在類內部方法呼叫不生效
UserServiceImpl測試實現類package cn.sw.study.web.service.impl;import cn.sw.study.web.dao.UserMapper;import cn.sw.study.web.model.User;import cn.sw.study.web.ser
spring AOP獲取切面方法資訊 JoinPoint的用法
JoinPoint 物件 封裝了SpringAop中切面方法的資訊,在切面方法中新增JoinPoint引數,就可以獲取到封裝該方法資訊的物件 常用api ; 方法名 功能 Signature getSignature();
Spring AOP專案應用——方法入參校驗 & 日誌橫切
應用一:方法入參校驗由於系統多個方法入參均對外封裝了統一的Dto,其中Dto中幾個必傳引數在每個方法中都會進行相同的校驗邏輯。筆者考慮採用Spring AOP進行優化,攔截方法進行引數校驗。測試case
Spring AOP 各種攔截方法執行的順序
AOPImpl.java ================== package salesdepart.service.app; import org.aspectj.lang.annotation.*; import org.aspectj.lang.*; import
spring 本類中方法呼叫另外一個方法事務不生效
1、在spring配置檔案中新增 <aop:aspectj-autoproxy expose-proxy="true"/&g
spring 同一個類中方法呼叫 註解不起作用
spring 同一個類中方法呼叫 註解不起作用 需要新增 AopContext.currentProxy() 這樣
【框架】[Spring]AOP攔截-三種方式實現自動代理
這裡的自動代理,我講的是自動代理bean物件,其實就是在xml中讓我們不用配置代理工廠,也就是不用配置class為org.springframework.aop.framework.ProxyFactoryBean的bean。 總結了一下自己目前所學的知識
Spring AOP中的JDK和CGLib動態代理哪個效率更高?
一、背景 今天有小夥伴面試的時候被問到:Spring AOP中JDK 和 CGLib動態代理哪個效率更高? 二、基本概念 首先,我們知道Spring AOP的底層實現有兩種方式:一種是JDK動態代理,另一種是CGLib的方式。 自Java 1.3以後
Spring aop利用jdk的InvocationHandler產生動態代理
筆記之用…… 首先有一個介面UserService package com.spring.test; import org.springframework.stereotype.Component; @Component public interface Use
Spring AOP簡介與底層實現機制——動態代理
AOP簡介 AOP (Aspect Oriented Programing) 稱為:面向切面程式設計,它是一種程式設計思想。AOP 是 OOP(面向物件程式設計 Object Oriented Programming)的思想延續 AOP採取橫向抽取機制,取代了傳統縱向繼承體系重複性程式碼的編寫方式(例如
spring aop無法攔截類內部的方法呼叫
1.概念 攔截器的實現原理就是動態代理,實現AOP機制。Spring 的代理實現有兩種:一是基於 JDK Dynamic Proxy 技術而實現的;二是基於 CGLIB 技術而實現的。如果目標物件實現了介面,在預設情況下Spring會採用JDK的動態代理實現AOP 2.問題 在類C中,方法A呼叫方法B, B方
spring中mock RestTemplate和FeignClient(mock方法內部的方法呼叫)
目的 要測試ServiceImpl類中的方法methodA 難點 methodA中呼叫了restTemplate的方法或者FeignClient的方法,而這兩個方法都依賴第三方應用,如果第三方應用沒有準備好,則會報錯,為了在單元測試中不依賴第三方應用,因此需要mock他們。