文章目录
一、动态代理介绍
动态代理:是使用反射和字节码的技术,在运行期创建指定接口或类的子类以及其实例对象的技术,通过这个技术可以无侵入的为代码进行增强。
二、动态代理的实现方式
Java中动态代理主要有JDK和CGLIB两种方式。
三、JDK实现的动态代理
1.JDK实现动态代理介绍。
JDK实现的动态代理由两个重要的成员组成,分别是Proxy、InvocationHandler
-
Proxy: 是所有动态代理的父类,它提供了一个静态方法来创建动态代理的class对象和实例
-
InvocationHandler: 每个动态代理实例都有一个关联的InvocationHandler,在代理实例上调用方法是,方法调用将被转发到InvocationHandler的invoke方法
2. 代码实现
2.1 创建代理类接口
package com.design.pattern.proxy.dynamic;
public interface ILoginService {
void login(LoginParam param);
}
LoginParam
package com.design.pattern.proxy.dynamic;
public class LoginParam {
private String name;
private String password;
public LoginParam() {
}
public LoginParam(String name, String password) {
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "LoginParam{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
2.2 创建业务实现
package com.design.pattern.proxy.dynamic;
public class LoginServiceImpls implements ILoginService{
@Override
public void login(LoginParam param) {
System.out.println("LoginServiceImpls 被调用........ ");
System.out.println("正在登录,登录信息为:"+ param.toString());
System.out.println("LoginServiceImpls 调用结束........ ");
}
}
2.3 实现InvocationHandler 接口
package com.design.pattern.proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class LoginInvocationHandler implements InvocationHandler {
private Object object;
public LoginInvocationHandler(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("LoginInvocationHandler 被调佣... ");
if (args != null && args.length > 0 && args[0] instanceof LoginParam){
LoginParam param = (LoginParam)args[0];
//进行增强判断
System.out.println("name:" + param.getName() + " psd:" + param.getPassword());
}
Object result = method.invoke(object, args);
System.out.println("login 成功... ");
System.out.println("LoginInvocationHandler 调佣结束... ");
return result;
}
}
2.4创建代理类
package com.design.pattern.proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class TestProxyDynamicJDK {
public static void test() {
LoginParam loginParam = new LoginParam();
loginParam.setName("wangwu");
loginParam.setPassword("123456");
//被代理类
ILoginService delegate = new LoginServiceImpls();
InvocationHandler userServiceInterceptor = new LoginInvocationHandler(delegate);
System.out.println("========================================================");
//动态代理类
ILoginService loginServiceProxy = (ILoginService) Proxy.newProxyInstance(
delegate.getClass().getClassLoader(),
delegate.getClass().getInterfaces(), userServiceInterceptor);
loginServiceProxy.login(loginParam);
System.out.println("========================================================");
}
}
2.5 打印结果
System.out: ========================================================
System.out: LoginInvocationHandler 被调佣...
System.out: name:wangwu psd:123456
System.out: LoginServiceImpls 被调用........
System.out: 正在登录,登录信息为:LoginParam{name='wangwu', password='123456'}
System.out: LoginServiceImpls 调用结束........
System.out: login 成功...
System.out: LoginInvocationHandler 调佣结束...
System.out: ========================================================