===================
动态代理是在装饰者模式下的加强版,我们一个类里有很多方法,但是如果我们要在每个方法都加一行helloword
这样就很麻烦,就可以通过动态代理来实现
class Test1
{
public static void main(String[] args)
{
ClassLoader loader1 = ClassLoader.getSystemClassLoader(); // 类加载器
Class[] clazz ={ PersonDao.class };//传入接口,如果PersonImp实现2个接口,那么这里要加个逗号填写第二个接口
PersonDao target = new PersonImp(); // 目标对象
MyInvocationHandler h = new MyInvocationHandler(target);// 处理器处理目标对象
// 动态创建代理对象proxy,会自动调用第3个参数类的invoke方法
PersonDao proxy = (PersonDao) Proxy.newProxyInstance(loader1, clazz, h);
//这个insert方法是我们本来的类的方法,现在交给代理来使用,且会自动调用处理程序里的invoke
proxy.insert(new Person());
}
}
interface PersonDao
{
public void insert(Person p);
public void update(Person p);
}
class PersonImp implements PersonDao
{
@Override
public void insert(Person p)
{
System.out.println("insert");
}
@Override
public void update(Person p)
{
System.out.println("update");
}
}
class MyInvocationHandler implements InvocationHandler// InvocationHandler(请求处理程序)
{
private Object target; // 目标对象
MyInvocationHandler(Object target) // 通过构造函数把目标对象传进来
{
this.target = target;
}
@Override
// 这个方法会被自动调用
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
System.out.println("myfucker"); // 先打印我们的需求,然后再通过目标对象打印对应的方法
Object ret = method.invoke(target, args);// 在目标对象上调用方法,args是我们传进来的方法
// 这个method是反射,需要目标对象和参数
return ret; // 这个的方法值,就是我们上面invoke返回后的返回值,因为我们相当于在重写一个invoke
}
}
class Person
{
private String name;
Person() // 这样就不可以new了
{
System.out.println("无参构造方法");
}
public String getName()
{
System.out.println("=====getName");
return name;
}
public void setName(String name)
{
System.out.println("setName");
this.name = name;
}
}