java----代理

代理

作用

  • 功能增强 
  • 控制访问

静态代理

  代理对象已经存在

动态代理

   代理对象依靠反射创建

 

 

 

 面向切面编程:

通过动态代理+加配置文件

目的解耦

给主逻辑添加一些修饰功能,但是不在主逻辑代码中进行修改,有点类似python中的装饰器,调用方法还是是通过接口的那个类来调用:

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Properties;

public class Demo {
    public static void main(String[] args) {
        //读取配置文件
        InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com\\first\\conf.properties");
        //获取bean的工厂
        BeanFactory beanFactory = new BeanFactory(resourceAsStream);
        ProxyFactorybean bean = ((ProxyFactorybean) beanFactory.getBean("bean"));
        //获取代理对象 ,注意:需要用 target的继承的接口来 cast
        Action proxy = ((Action) bean.getProxy());
        proxy.test();
    }
}

interface Advice{
    public void berforeAdvice();
    public void afterAdvice();
}
class LoginAdvice implements Advice{
    @Override
    public void berforeAdvice() {
        System.out.println("开始添加日志"+System.currentTimeMillis());
    }
    @Override
    public void afterAdvice() {
        System.out.println("结束添加日志"+System.currentTimeMillis());
    }
}

interface Action{
    public void test();
}
class IManage implements Action{
    public void test(){
        System.out.println("执行添加功能");
    }
}

//工厂(生产代理对象)
class ProxyFactorybean implements InvocationHandler{
    //被代理对象
    private Object target;
    //切片对象
    private Advice advice;
    //生产代理对象
    public Object getProxy(){
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        return proxy;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        advice.berforeAdvice();
        method.invoke(target,args);
        advice.afterAdvice();
        return null;
    }
    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }

    public Advice getAdvice() {
        return advice;
    }

    public void setAdvice(Advice advice) {
        this.advice = advice;
    }
}

//工厂(生产Bean)
class BeanFactory{
    Properties prop = new Properties();
    public BeanFactory(InputStream in){
        try {
            prop.load(in);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //获取一个Bean实例,通过反射的方式动态创建;
    public Object getBean(String name){
        Object bean=null;
        String className = prop.getProperty(name);
        try {
            Class<?> aClass = Class.forName(className);
            bean = aClass.newInstance();
            //创建目标对象
            Object target = Class.forName(prop.getProperty(name + ".target")).newInstance();
            //创建切片对象
            Object advice = Class.forName(prop.getProperty(name + ".advice")).newInstance();
            //创建bean属性描述器
            BeanInfo beanInfo = Introspector.getBeanInfo(aClass);
            //通过内省内省实现对bean对象的属性赋值
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (int i = 0; i < propertyDescriptors.length; i++) {
                String name1 = propertyDescriptors[i].getName();
                Method writeMethod = propertyDescriptors[i].getWriteMethod();
                if ("target".equals(name1)){
                    writeMethod.invoke(bean,target);
                }
                if ("advice".equals(name1)){
                    writeMethod.invoke(bean,advice);
                }
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return bean;
    }
}

  

posted @ 2019-04-23 13:38  小名的同学  阅读(269)  评论(0编辑  收藏  举报