一、静态代理步骤详解:
1.声明目标对象的接口;UserService.java
public interface UserService {
public void addUser(String name);
}
2.声明目标对象类并实现接口:UserServiceImpl.java
//实际对象
public class UserServiceImpl implements UserService{
@Override
public void addUser(String name) {
System.out.println("调用addUser()方法新增用户:"+name);
}
}
3.定义代理类:StaticProxy.java
public class StaticProxy{
private UserService target;//代理对象
public StaticProxy(UserService target){ //通过构造方法传入被代理对象
this.target=target;
}
public void invoke(String name){
System.out.println("静态代理开始");
this.target.addUser(name);
System.out.println("静态代理结束");
}
}
4.测试结果:
public class TestProxy {
public static void main(String []args){
UserService target=new UserServiceImpl();
target.addUser("张三");//调用函数直接实现
new StaticProxy(target).invoke("张三");//使用静态代理实现
}
}
JDK动态代理步骤:
1.创建被代理的接口;UserService.java
public interface UserService {
public void addUser(String name);
}
2.创建被代理类并实现接口:UserServiceImpl.java
//实际对象
public class UserServiceImpl implements UserService{
@Override
public void addUser(String name) {
System.out.println("调用addUser()方法新增用户:"+name);
}
}
②创建InvocationHandler接口的实现类,在invoke方法中实现代理逻辑:DynamicProxy.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxy implements InvocationHandler{
private UserService target;//声明代理对象
public DynamicProxy(UserService target){
this.target=target;
}
//动态代理对象调用目标对象的任何方法前,都会调用调用处理器类的invoke(),在invoke方法中实现代理逻辑。
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
// 参数说明:
// 参数1:动态代理对象(即哪个动态代理对象调用了method()
// 参数2:目标对象被调用的方法
// 参数3:指定被调用方法的参数
System.out.println("动态代理调用开始!");
Object result=method.invoke(target, args);// 通过Java反射机制调用目标对象
System.out.println("动态代理调用结束!");
return result;
}
}
4.测试:TestDynamicProxy.java
③通过Proxy的静态方法newProxyInstance( ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理对象
import java.lang.reflect.Proxy;
public class TestDynamicProxy {
public static void main(String[] args) {
//动态代理调用的方式:
//1.创建目标对象对象
UserService target=new UserServiceImpl();
//2.创建调用处理器类的对象
DynamicProxy myhandler=new DynamicProxy(target);
//3. 创建动态代理类 &对象:通过调用处理器类对象newProxyInstance(),传入上述目标对象对象
UserService userService = (UserService) Proxy.newProxyInstance(TestDynamicProxy.class.getClassLoader(), target.getClass().getInterfaces(), myhandler);
userService.addUser("张三");
}
}
静态代理和动态代理:
既然有了静态代理,为什么会出现动态代理呢?说一下静态代理的一些缺点吧:
①代理类和被代理类实现了相同的接口,导致代码的重复,如果接口增加一个方法,那么除了被代理类需要实现这个方法外,代理类也要实现这个方法,增加了代码维护的难度。
②代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。比如上面的例子,只是对用户的业务功能(IUserService)进行代理,如果是商品(IItemService)的业务功能那就无法代理,需要去编写商品服务的代理类。
于是乎,动态代理的出现就能帮助我们解决静态代理的不足。所谓动态代理是指:在程序运行期间根据需要动态创建代理类及其实例来完成具体的功能。动态代理主要分为JDK动态代理和cglib动态代理两大类,本文主要对JDK动态代理进行探讨。