Java动态代理

    前几天看公司的项目,发现一个类的注入怎么都找不到它的实现类,但是项目的注入又是成功的。

    深入看了一下才发现原理:

    

1、tops-order-dao项目依赖jar包tops-member-client,jar包member-client-service.xml中配置pCustomerService

<bean id="pCustomerService" class="com.travelzen.tops.member.client.service.MemberThriftClientServiceProxy"

p:interface="com.travelzen.tops.member.common.iservice.CustomerService" />

2、MemberThriftClientServiceProxy实现SmartFactoryBean(继承FactoryBean)接口,Spring中如果一个类实现了FactoryBean接口,那么不会直接把这个类返还给调用着,而是返回FactoryBean::getObject的类型

在MemberThriftClientServiceProxy.getObject中采用动态代理返回CustomerServiceProxy类,在实现InvocationHandler.invoke方法中进行业务处理,这时CustomerService经过代理是可以初始化成功的。

3、InvocationHandler.invoke首先获取Thrift的MemberService.Iface,然后按照接口名称,方法,参数等调用Thrift接口

4、在Thrift的server端MemberThriftServiceImpl实现了MemberService.Iface这个接口,首先按照接口查找对应的实现类:Object svc = services.get(tReq.getDeclaredInterface()) (services是通过Spring上下文获取

MemberThriftServer.initServiceMethods)

services的初始化是采用注解:Component下的@PostConstruct

5、通过反射调用目标类

server端通过启动一个线程MemberServerStartupServlet.init-->memberThriftServer.startThreadedSelectorServer监听需要处理的方法

        

主要步骤是在这些,模拟一下:

1、定义一个接口:

            package com.java.proxy.interfaces;

            

            public interface IHello {

            void sayHello();

            }

2、定义一个接口的实现类:

            

        package com.java.proxy.impl;


        import com.java.proxy.interfaces.IHello;

        

        public class HelloImpl implements IHello {

        

        @Override

        public void sayHello() {

        System.out.println("hello java proxy!");

        }

        

        }

3、把实现类和接口放到一个容器中,也可以动态扫描,都是可以的     

        package com.java.proxy;

        

        import java.util.HashMap;

        import java.util.Map;

        

        import com.java.proxy.impl.HelloImpl;

        import com.java.proxy.interfaces.IHello;

        

        public class InterfaceProxyContainer {

        private static Map<String,Class<?>> containers = new HashMap<String,Class<?>>();

        

        static{

        containers.put(IHello.class.getName(), HelloImpl.class);

        }

        

        public static  Map<String,Class<?>> containers(){

        return containers;

        }

        }

4、定义参数实体类

        

        package com.java.proxy;

        

        public class ProxyBean {

        

        private String interfaceName;

        private String methodName;

        private String paramArgs;

        

        public String getInterfaceName() {

        return interfaceName;

        }

        

        public void setInterfaceName(String interfaceName) {

        this.interfaceName = interfaceName;

        }

        

        public String getMethodName() {

        return methodName;

        }

        

        public void setMethodName(String methodName) {

        this.methodName = methodName;

        }

        

        public String getParamArgs() {

        return paramArgs;

        }

        

        public void setParamArgs(String paramArgs) {

        this.paramArgs = paramArgs;

        }

        }

5、定义代理的目标执行类

        

        package com.java.proxy;

        

        import java.lang.reflect.Method;

        

        public class InvokeProxy {

        private ProxyBean proxyBean;

        

        private Object rtValue;

        

        public void setProxyBean(ProxyBean proxyBean) {

        this.proxyBean = proxyBean;

        }

        

        public Object getRtValue() {

        return rtValue;

        }

        

        public void invoke(){

        Class<?> clazz = InterfaceProxyContainer.containers().get(proxyBean.getInterfaceName());

        try {

        Method method = clazz.getDeclaredMethod(proxyBean.getMethodName());

        System.out.println(proxyBean.getParamArgs().equals("null"));

        if(proxyBean.getParamArgs().equals("null"))

        rtValue = method.invoke(clazz.newInstance());

        else

        rtValue = method.invoke(clazz.newInstance(), proxyBean.getParamArgs()).toString();

        } catch (Exception e) {

        e.printStackTrace();

        }

        }

        }

6、定义代理类      

        package com.java.proxy;

        

        import java.lang.reflect.InvocationHandler;

        import java.lang.reflect.Method;

        import java.lang.reflect.Proxy;

        import java.util.Arrays;

        

        public class SimpleProxy {

        private Class<?> clazz;

        

        public void setClazz(Class<?> clazz) {

        this.clazz = clazz;

        }

        

        public Object proxy() {

        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class<?>[] {clazz}, new InvocationHandler() {

        

        @Override

        public Object invoke(Object proxy, Method method, Object[] args)

        throws Throwable {

        ProxyBean proxyBean = new ProxyBean();

        proxyBean.setInterfaceName(clazz.getName());

        proxyBean.setMethodName(method.getName());

        proxyBean.setParamArgs(Arrays.toString(args));

        InvokeProxy invokeProxy = new InvokeProxy();

        invokeProxy.setProxyBean(proxyBean);

        invokeProxy.invoke();

        return invokeProxy.getRtValue();

        }

        });

        }

        }

 7、测试

        package com.java.proxy;

        

        import com.java.proxy.interfaces.IHello;

        

        public class Test {

        public static void main(String[] args) {

        SimpleProxy simpleProxy = new SimpleProxy();

        simpleProxy.setClazz(IHello.class);

        IHello ihello = (IHello) simpleProxy.proxy();

        ihello.sayHello();

        }

        }

         结果:

        true

        hello java proxy!

        其实就是在代理类中使用反射,执行真正需要执行的类,对于返回结果,由代理类获取代理执行类的rtValue


        在Spring的HttpInvoker中是否也是这样的??

        

你可能感兴趣的:(动态代理,spring,httpinvoker)