Java靜態(tài)代理和動態(tài)代理總結(jié)
靜態(tài)代理
第一種實現(xiàn)(基于接口):
1》接口
public interface Hello {
void say(String msg);
}
2》目標類,至少實現(xiàn)一個接口
public class HelloImpl implements Hello {
public void say(String msg) {
System.out.println("Hi,"+msg);
}
}
3》代理類(與目標類實現(xiàn)相同接口,從而保證功能一致)
public class HelloProxy implements Hello{
private Hello hello;
public HelloProxy(Hello hello){
this.hello = hello;
}
public void say(String msg){
before();
hello.say(msg);
after();
}
private void before(){
System.out.println("Before");
}
private void after(){
System.out.println("After");
}
}
3》測試
/**
* @Author LZHL
* @Create 2017-02-19 10:26
* @Description
*/
public class Main {
public static void main(String[] args) throws Exception {
HelloImpl target = new HelloImpl();
HelloProxy proxy = new HelloProxy(target);
proxy.say("LZHL");
}
}
第二種實現(xiàn)(基于目標類):
1>目標類
public class HelloTarget {
public void sayHello(String name){
System.out.println("Hi,"+name);
}
}
2>代理類(通過繼承目標類,保證功能一致)
public class HelloProxy extends HelloTarget{
private HelloTarget target;
public HelloProxy(HelloTarget target){
this.target = target;
}
@Override
public void sayHello(String name) {
this.before();
target.sayHello(name);
this.after();
}
private void before(){
System.out.println("Before");
}
private void after(){
System.out.println("After");
}
}
3>測試
public class Main {
public static void main(String[] args) throws Exception {
HelloTarget target = new HelloTarget();
HelloProxy proxy= new HelloProxy(target);
proxy.sayHello("LZHL");
}
}
動態(tài)代理
動態(tài)代理的代理類是在程序運行期間動態(tài)生成的,也有兩種實現(xiàn),一種是JDK動態(tài)代理,一種是CGLib動態(tài)代理
1》JDK動態(tài)代理(基于接口實現(xiàn),與目標類實現(xiàn)相同接口,從而保證功能一致)
/**
* @Author LZHL
* @Create 2017-02-19 12:46
* @Description
*/
public class Main {
public static void main(String[] args){
final HelloImpl target = new HelloImpl();
Object proxyInstance = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
/*
* proxy: 代理對象
* method: 目標對象的方法對象
* args: 目標對象方法的參數(shù)
* return: 目標對象方法的返回值
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object retValue = method.invoke(target, args);
System.out.println("after");
return retValue;
}
});
Hello proxy = (Hello) proxyInstance;
proxy.say("LYX");
//可以把InvocationHandler提取出來,單獨寫一個類,為了方便大家看,這里我用內(nèi)部類的形式
class JDKProxy implements InvocationHandler {
private Object target;
public JDKProxy(Object target){
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(target, args);
after();
return result;
}
private void before(){
System.out.println("Before");
}
private void after(){
System.out.println("After");
}
}
InvocationHandler ih = new JDKProxy(target);
Object proxyInstance2 = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), ih);
Hello proxy2 = (Hello) proxyInstance2;
proxy2.say("LZHL");
}
}
2》CGLib動態(tài)代理(基于目標類,通過繼承目標類,從而保證功能一致),需要導(dǎo)入cglib-3.2.4.jar包
pom.xml
<dependencies> <!-- https://mvnrepository.com/artifact/cglib/cglib --> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.4</version> </dependency> </dependencies>
1)目標類
public class Hi {
public void sayHi(String msg){
System.out.println("Hi,"+msg);
}
}
2)測試
/**
* @Author LZHL
* @Create 2017-02-19 13:19
* @Description
*/
public class Main {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
//設(shè)置父類
enhancer.setSuperclass(Hi.class);
//設(shè)置回調(diào)函數(shù)
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("before");
Object retValue = methodProxy.invokeSuper(target, args);
System.out.println("after");
return retValue;
}
});
Object proxy = enhancer.create();
Hi hi = (Hi) proxy;
hi.sayHi("LXY");
//可以把MethodInterceptor提取出來,單獨寫一個類,為了方便大家看,這里我用內(nèi)部類的形式
class CGLibProxy implements MethodInterceptor {
public <T> T getProxy(Class<T> clazz){
return (T) Enhancer.create(clazz, this);
}
public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
before();
Object result = proxy.invokeSuper(target, args);
after();
return result;
}
private void before(){
System.out.println("Before");
}
private void after(){
System.out.println("After");
}
}
CGLibProxy cgLibProxy = new CGLibProxy();
Hi hi2 = cgLibProxy.getProxy(Hi.class);
hi2.sayHi("LZHL");
}
}
以上所述是小編給大家介紹的Java靜態(tài)代理和動態(tài)代理總結(jié),希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復(fù)大家的!
相關(guān)文章
springboot實現(xiàn)防重復(fù)提交和防重復(fù)點擊的示例
這篇文章主要介紹了springboot實現(xiàn)防重復(fù)提交和防重復(fù)點擊的示例,幫助大家更好的理解和學(xué)習(xí)springboot框架,感興趣的朋友可以了解下2020-09-09
java?MultipartFile文件上傳重命名詳細代碼示例
在文件上傳功能開發(fā)中,為防止文件重名導(dǎo)致數(shù)據(jù)覆蓋,常見的做法是在文件名前加上UUID或時間戳來區(qū)分,這篇文章主要介紹了java?MultipartFile?multipartFile文件上傳重命名的相關(guān)資料,需要的朋友可以參考下2024-09-09
springboot整合springsecurity與mybatis-plus的簡單實現(xiàn)
Spring Security基于Spring開發(fā),項目中如果使用Spring作為基礎(chǔ),配合Spring Security做權(quán)限更加方便,而Shiro需要和Spring進行整合開發(fā)。因此作為spring全家桶中的Spring Security在java領(lǐng)域很常用2021-10-10
RestTemplate設(shè)置超時時間及返回狀態(tài)碼非200處理
這篇文章主要為大家介紹了RestTemplate設(shè)置超時時間及返回狀態(tài)碼非200處理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06
解決spring結(jié)合mybatis時一級緩存失效的問題
這篇文章主要介紹了解決spring結(jié)合mybatis時一級緩存失效的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
Springboot如何設(shè)置靜態(tài)資源緩存一年
這篇文章主要介紹了Springboot如何設(shè)置靜態(tài)資源緩存一年,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11

