动态代理
方法的作用:在运行时,动态实现一组指定的接口的实现类对象!(在运行时,创建实现了指定的一组接口的对象)
interface A{
}
interface B{
}
Object o=方法(new Class[]{A.class,b.class})
o实现了A和B接口!
动态代理的作用
最终是学习AOP(面向切面编程),它与装饰者模式有点相似,它比装饰者模式更灵活。
这个invoke()方法在什么时候被调用
在调用代理对象所实现接口中的方法时被调用。
Object proxy:当前对象,即代理对象。在调用谁的方法!
Method method:当前被调用的方法(目标方法)
Object[] args:实参
public class AProxy {
@Test
public void fun1() {
/*代理类
*
* 三大参数
* 1.ClassLoader
* 方法需要动态生成一个类,这个类实现了A,B接口,然后创建了这个类的对象!
* 需要生成一个类,这个类也需要加载到方法区中,谁来加载,当然是ClassLoader
*
* 2.Class[] interfaces
* 它是要实现的接口们
*
* 3.InvocationHandler
* 他是调用处理器
*
* 代理对象的实现的所有接口中的方法,内容都是调用InvocationHandler的invoke()方法
*
* */
ClassLoader loader=this.getClass().getClassLoader();
InvocationHandler h =new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("动态代理");
return args;
}
};
//使用3大参数创建对象
Object o =Proxy.newProxyInstance(loader, new Class[] {A.class,B.class}, h);
//强转成A和B类型,成功了
A a =(A)o;
B b=(B)o;
a.a();
b.b();
//o.toString();
//o.equals(null);
//o.getClass();//这个不会执行invoke()方法
String cc=a.bb("hello");
System.out.println(cc);
}
}
interface A{
public void a();
public String bb(String a);
}
interface B{
public void b();
}
上述为简单的代理
public class Demo2 {
@Test
public void fun1() {
Waiter manWaiter=new ManWaiter();
ClassLoader loader=this.getClass().getClassLoader();
Class[] interfaces= {Waiter.class};
InvocationHandler h =new WaiterInvocationHandler(manWaiter);
//得到代理对象,代理对象就是在目标对象增强的对象
Waiter waiterProxy=(Waiter)Proxy.newProxyInstance(loader, interfaces, h);
waiterProxy.serve();
}
}
class WaiterInvocationHandler implements InvocationHandler{
private Waiter waiter;
public WaiterInvocationHandler(Waiter waiter) {
this.waiter=waiter;
// TODO Auto-generated constructor stub
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("你好!");
this.waiter.serve();
System.out.println("再见!");
return null;
}
}
public interface Waiter {
public void serve();
}
public class ManWaiter implements Waiter{
@Override
public void serve() {
System.out.println("服务中。。。");
}
}
以上为第二种
public interface Waiter {
public void serve();
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
* 它用来生成代理对象
* 它需要所有的参数
* 目标对象
* 增强
* */
/**
* 1.创建代理工厂 2.给工厂设置三样东西: 目标对象:setTargetObject(XXX);
* 前置增强:setBeforeAdvice(该接口的实现); 后置增强:setAfterAdvice(该接口的实现); 3.调用createProxy()
* 得到代理对象 执行代理对象的目标方法 执行BeforeAdvice的after() 目标对象的目标方法 执行AfterAdvice的after()
*/
public class ProxyFactory {
private Object targetObject;// 目标对象
private BeforeAdvice beforeAdvice;// 前置增强
private AfterAdvice afterAdvice;// 后置增强
/*
* 用来生成代理对象
*/
public Object createProxy() {
ClassLoader loader = this.getClass().getClassLoader();
Class[] interfaces = targetObject.getClass().getInterfaces();
InvocationHandler h = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
if (beforeAdvice != null) {
beforeAdvice.before();
}
Object result = method.invoke(targetObject, args);// 调用目标对象的目标方法
if (afterAdvice != null) {
afterAdvice.after();
}
return result;
}
};
Object proxyObject=Proxy.newProxyInstance(loader, interfaces, h);
return proxyObject;
}
public Object getTargetObject() {
return targetObject;
}
public void setTargetObject(Object targetObject) {
this.targetObject = targetObject;
}
public BeforeAdvice getBeforeAdvice() {
return beforeAdvice;
}
public void setBeforeAdvice(BeforeAdvice beforeAdvice) {
this.beforeAdvice = beforeAdvice;
}
public AfterAdvice getAfterAdvice() {
return afterAdvice;
}
public void setAfterAdvice(AfterAdvice afterAdvice) {
this.afterAdvice = afterAdvice;
}
}
public class ManWaiter implements Waiter{
@Override
public void serve() {
System.out.println("服务中。。。");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import org.junit.Test;
public class Demo2 {
@Test
public void fun1() {
ProxyFactory factory=new ProxyFactory();//创建工厂
factory.setTargetObject(new ManWaiter());//设置目标对象
factory.setBeforeAdvice(new BeforeAdvice() {//设置前置增强
public void before() {
System.out.println(“您好:”);
}
});
factory.setAfterAdvice(new AfterAdvice() {//设置后置增强
public void after() {
System.out.println("再见!haha ");
}
});
Waiter waiter=(Waiter)factory.createProxy();
waiter.serve();
}
}
class WaiterInvocationHandler implements InvocationHandler{
private Waiter waiter;
public WaiterInvocationHandler(Waiter waiter) {
this.waiter=waiter;
// TODO Auto-generated constructor stub
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("你好!");
this.waiter.serve();
System.out.println("再见!");
return null;
}
}
public class BeforeAdvice {
public void before() {
// TODO Auto-generated method stub
}
}
public class AfterAdvice {
public void after() {
// TODO Auto-generated method stub
}
}
//第二种就是代理模式的简单应用,
而第三种则是创建了一个工厂模式,利用这个工厂类,可以组装出各种格式的代理类
代理类的重点:
代理类的第一个重点就是InvocationHandler
InvocationHandler :其实就是利用在这个类中执行,在目标方法的前后添加一些业务逻辑。这就是代理模式。
第二个重点就是:
Proxy.newProxyInstance(loader, interfaces, h);
这个类的三个参数是最重要的方法。利用这个方法,可以实例化该类。
总的来说,代理模式,其实就是将前置增强和后置增强与目标方法装配起来。让这个类能够做更多的事。有利于拓展。
弄懂了这个,其实就是为了更好的学习AOP。