spring動態代理
❶ spring的動態代理有幾種實現方式
JAVA 代理實現
代理的實現分動態代理和靜態代理,靜態代理的實現是對已經生成了的JAVA類進行封裝。
動態代理則是在運行時生成了相關代理累,在JAVA中生成動態代理一般有兩種方式。
JDK自帶實現方法
JDK實現代理生成,是用類 java.lang.reflect.Proxy, 實現方式如下
EX:
publicclassJDKProxy{
(finalObjectc){
returnProxy.newProxyInstance(c.getClass().getClassLoader(),c.getClass().getInterfaces(),//JDK實現動態代理,但JDK實現必須需要介面
newInvocationHandler(){
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
//TODOAuto-generatedmethodstub
ObjectreObj=null;
System.out.print("yousay:");
reObj=method.invoke(c,args);
System.out.println("["+Calendar.getInstance().get(Calendar.HOUR)+":"
+Calendar.getInstance().get(Calendar.MINUTE)+""
+Calendar.getInstance().get(Calendar.SECOND)+"]");
returnreObj;
}
});
}
}
測試代理類方法
publicclassTestForPoxy{
publicstaticvoidmain(String[]args){
ServiceTestservice=newServiceTestImpl();
System.out.println(service.getClass().getSimpleName());
ServiceTestpoxyService=(ServiceTest)JDKProxy.getPoxyObject(service);
System.out.println(poxyService.getClass().getSuperclass());
poxyService.saySomething("hello,MyQQcodeis107966750.");
poxyService.saySomething("what'syourname?");
poxyService.saySomething("onlyfortest,hehe.");
}
}
1, Proxy實現代理的目標類必須有實現介面
2, 生成出來的代理類為介面實現類,和目標類不能進行轉換,只能轉為介面實現類進行調用
明顯特點:通過此方法生成出來的類名叫做 $Proxy0
用CGLIB包實現
CGLIB是一個開源項目,官方網址是:http://cglib.sourceforge.net/,可以去上面下載最新JAR包,
本項目用的是cglib-3.0.jar
本項目還加入了依賴JAR包asm-4.0.jar,asm-util-4.0.jar
實現方式如下
EX:
publicclassCGLIBProxy{
(Objectc){
Enhancerenhancer=newEnhancer();
enhancer.setSuperclass(c.getClass());
enhancer.setCallback(newMethodInterceptor(){
publicObjectintercept(Objectarg0,Methodarg1,Object[]arg2,MethodProxyproxy)throwsThrowable{
System.out.print("yousay:");
proxy.invokeSuper(arg0,arg2);
System.out.println("["+Calendar.getInstance().get(Calendar.HOUR)+":"
+Calendar.getInstance().get(Calendar.MINUTE)+""+Calendar.getInstance().get(Calendar.SECOND)
+"]");
returnnull;
}
});
returnenhancer.create();
}
}
測試代理類方法
publicclassTestForPoxy{
publicstaticvoidmain(String[]args){
ServiceTestservice=newServiceTestImpl();
System.out.println(service.getClass().getSimpleName());
//ServiceTestpoxyService=(ServiceTest)JDKProxy.getPoxyObject(service);
ServiceTestpoxyService=(ServiceTest)CGLIBProxy.getPoxyObject(service);
System.out.println(poxyService.getClass().getSuperclass());
poxyService.saySomething("hello,MyQQcodeis107966750.");
poxyService.saySomething("what'syourname?");
poxyService.saySomething("onlyfortest,hehe.");
}
}
1, CGLIB實現方式是對代理的目標類進行繼承
2, 生成出了的代理類可以沒方法,生成出來的類可以直接轉換成目標類或目標類實現介面的實現類,因JAVA向上轉換
明顯特點:通過輸出看出,看出生成出的代理類的parent類為代理的目標類
❷ 如何在spring容器里注冊自定義的動態代理生成的對象(類似mybatis的注入)
請問有解決了嗎?我也在看這塊,你看看我這種方法行不行:
@n
@ComponentScan(basePackages = "com.minsx.spring.jpatemplateb")
public class AppConfig implements ApplicationContextAware {
@Autowired
RepositoryProxyFactory repositoryFactory;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
registerBeans(applicationContext);
}
private void registerBeans(ApplicationContext applicationContext) throws BeansException {
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(getUserRepositoryProxy().getClass());
defaultListableBeanFactory.registerBeanDefinition("userRepository", beanDefinitionBuilder.getBeanDefinition());
}
private UserRepository getUserRepositoryProxy() {
System.out.println(JSON.toJSONString(repositoryFactory.getProxyByClass(UserRepository.class).findUserByName("goodsave")));
return repositoryFactory.getProxyByClass(UserRepository.class);
}
}
❸ jdk 動態代理與spring 動態代理區別
spring有兩種動態代理方式,一種就是jdk動態代理,還有就是cglib動態代理,jdk動態代理只能代理介面,cglib可以是類。jdk代理生成速度比cglib快,性能沒有cglib好
❹ Spring 動態代理問題!
首先,這是抄動態代理,但是和spring裡面的AOP沒有直接關系.
你還是做的是java本身的"動態代理".
因為你做的是動態代理,所以你的類必須實現InvocationHandler介面.
自然,你的實現類"Daili"就必須實現invoke()方法,這個方法是在你調用被代理對象的時候自動執行的,所以不需要你顯式調用.
實際過程是你要執行被代理對象裡面的某個method,這是你的目的(賣電腦),這時你要通過代理對象來做,因為代理對象可以做一些其他的事情(比如:送橘子).
"賣電腦"和"送橘子"是一次營銷活動的組成部分,送完橘子你必須還要給人家電腦,這個invoke()方法就是在你送橘子的前、中、後去賣電腦,這個才是主要目的.
invoke()方法的參數列表是:Object proxy, Method method, Object[] args
指的是:被代理對象, 要執行的被代理對象中的方法, 要執行的方法中的參數列表
具體到你的例子:賣電腦的業務類, 賣電腦的那個方法, 賣電腦需要的一些數據
返回的是'賣電腦的那個方法'返回的數據,因為在編程時不知道運行時會去代理什麼,所以參數列表是個對象數組,返回的是個對象.
❺ Spring框架的動態代理是干什麼用的
主要就是解耦和。還有提高開發效率。易於修改啊。
比如 一段記錄日誌的代碼。loger.log("some mothed invoke at "+new Date()); 沒有什麼難事。但是你所有方法。你都復制一下?那個太不靠譜了。
嗯。這個就是Java 模式 中的 代理模式。你可以看一下。看看那個。你就知道了spring 的代理。嗯。spring的代理,有兩種機制,一中是jdk的Proxy 還有一個是cglib 這個是基於集成實現的。嗯。就是super 使用重寫方法。然後在重寫方法中加入 super.thisMethod();
耦合度太高的話就會對你的程序未來升級帶來恨大的麻煩。嗯。說實話啊。嗯。你的項目要是一頂保證永不改變。那麼完全可以不管這個耦合度的問題。但是,jdk的升級。還有其他框架啊。技術的升級。都會對你 的系統帶來問題。和升級空間。所以,降低耦合度就是一直在做的。
❻ spring中aop的動態代理機制有哪些
1.事務管理: (1)資料庫事務:(2)編程事務(3)聲明事物:Spring AOP-->聲明事物
2.日誌處理:
3.安全驗證: Spring AOP---OOP升級
靜態代理原理:目標對象:調用業務邏輯 代理對象:日誌管理
表示層調用--->代理對象(日誌管理)-->調用目標對象
動態代理原理:spring AOP採用動態代理來實現
(1)實現InvocationHandler介面
(2)創建代理類(通過java API)
❼ spring動態代理有什麼作用
可以在你執行被代理對象裡面的某個method前後自動執行任意你規定的代碼,而回不影響method其他相鄰方法的執行答,使代碼程序低耦合。
也可以寫一個不依賴與其他模塊的日誌管理模塊,然後用AOP來把這個模塊跟資料庫操作模塊掛鉤,在數據操作的同時也通過AOP功能自動的記錄了資料庫操作日誌。 當不需要日誌時,可直接移除而不影響其他的代碼。
❽ 如何將動態代理對象注入到spring
建議你把Proxy.newProxyInstance寫到一個工廠類裡面(因為其實Proxy.newInstance本身就是工廠模式)
❾ Spring的兩種動態代理有什麼區別
JAVA 代理實現
代理的實現分動態代理和靜態代理,靜態代理的實現是對已經生成了的JAVA類進行封裝。
動態代理則是在運行時生成了相關代理累,在JAVA中生成動態代理一般有兩種方式。
❿ spring對AOP的支持 JDK動態代理和CGLIB的區別
Aspect默認情況下不來用實現介面,但對源於目標對象(UserManagerImpl.java),在默認情況下必須實現介面
如果沒有實現介面必須引入CGLIB庫
我們可以通過Advice中添加一個JoinPoint參數,這個值會由spring自動傳入,從JoinPoint中可以取得
參數值、方法名等等
1、如果目標對象實現了介面,默認情況下會採用JDK的動態代理實現AOP
2、如果目標對象實現了介面,可以強制使用CGLIB實現AOP
3、如果目標對象沒有實現了介面,必須採用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換
如何強制使用CGLIB實現AOP?
* 添加CGLIB庫,SPRING_HOME/cglib/*.jar
* 在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
JDK動態代理和CGLIB位元組碼生成的區別?
* JDK動態代理只能對實現了介面的類生成代理,而不能針對類
* CGLIB是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法
因為是繼承,所以該類或方法最好不要聲明成final