v1.接口 Class<?> resourceClass
v2.获取builder
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(resourceClass);
v3.获取接口对应的动态代理class
Class<?> targetProxyClass = Proxy.getProxyClass(XXX.class.getClassLoader(), new Class[]{resourceClass});
v4.targetProxyClass构造参数类型 InvocationHandler,通过builder设置
builder.addConstructorArgValue(Proxy.getInvocationHandler(xxxProxyBean) 或者 new InvocationHandler(){...});
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
beanDefinition.setBeanClass(targetProxyClass);
registry.registerBeanDefinition("beanName", beanDefinition);
v5.记录一下自己曾经写的一个例子
v5.1 抽象类ProxyFactoryBean
package com.hjzgg.apigateway.soa.proxy; import com.hjzgg.apigateway.soa.exceptions.SoaException; import com.hjzgg.apigateway.soa.proxy.consumer.ConsumerProxyFactoryBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.util.ClassUtils; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; /** * Created by hujunzheng on 2017/7/7. */ public abstract class ProxyFactoryBean implements FactoryBean { protected Class<?> selfDynamicProxyClass;//代理类 protected Class<?> resourceClass;//接口类 protected String version;//dubbo 版本 protected String group;//dubbo 分组 protected Object proxy;//代理对象 protected Method createProxyMethod; public ProxyFactoryBean(Class<?> selfDynamicProxyClass, Class<?> resourceClass, String version, String group) throws SoaException { if (Objects.isNull(selfDynamicProxyClass)) { throw new SoaException("selfDynamicProxyClass 动态代理类不能为null"); } try { this.createProxyMethod = Stream.of(selfDynamicProxyClass.getMethods()) .filter(method -> Modifier.isStatic(method.getModifiers()) && Modifier.isPublic(method.getModifiers()) && !Modifier.isAbstract(method.getModifiers()) && method.getParameters().length == 2 && method.getParameters()[0].getType().equals(ProxyFactoryBean.class) && method.getParameters()[1].getType().equals(Class.class) && !method.getReturnType().equals(void.class)) .collect(Collectors.toList()) .get(0); } catch (Exception e) { throw new SoaException("500", String.format("%s %s %s和%s %s, %s %s" , ClassUtils.getQualifiedName(selfDynamicProxyClass) , " 没有参数类型是 " , ClassUtils.getQualifiedName(ConsumerProxyFactoryBean.class) , ClassUtils.getQualifiedName(Class.class) , " 的、公共的、非抽象的、返回值非void的方法" , "请将你的动态代理类继承" , ClassUtils.getQualifiedName(DynamicProxyAdapter.class) ), e); } this.selfDynamicProxyClass = selfDynamicProxyClass; this.resourceClass = resourceClass; this.version = version; this.group = group; } protected Object newInstance() throws SoaException { if(this.isSingleton() && this.proxy != null) { return proxy; } synchronized (this) { Object target; try { target = this.createProxyMethod.invoke(null,this, selfDynamicProxyClass); } catch (Exception e) { throw new SoaException("500", String.format("%s %s %s" , ClassUtils.getQualifiedName(selfDynamicProxyClass) , createProxyMethod.getName() , "创建代理类异常") , e); } if(proxy == null) { proxy = target; } return target; } } public Class<?> getSelfDynamicProxyClass() { return selfDynamicProxyClass; } public void setSelfDynamicProxyClass(Class<?> selfDynamicProxyClass) { this.selfDynamicProxyClass = selfDynamicProxyClass; } public Class<?> getResourceClass() { return resourceClass; } public void setResourceClass(Class<?> resourceClass) { this.resourceClass = resourceClass; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public String getGroup() { return group; } public void setGroup(String group) { this.group = group; } }
v5.2 ProxyFactoryBean具体实现类ProviderProxyFactoryBean
package com.hjzgg.apigateway.soa.proxy.provider; import com.hjzgg.apigateway.soa.exceptions.SoaException; import com.hjzgg.apigateway.soa.proxy.ProxyFactoryBean; import org.springframework.aop.SpringProxy; import org.springframework.aop.TargetClassAware; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @author hujunzheng * @create 2018-02-18 下午3:01 **/ public class ProviderProxyFactoryBean extends ProxyFactoryBean { public ProviderProxyFactoryBean(Class<?> selfDynamicProxyClass, Class<?> resourceClass, String version, String group) throws SoaException { super(selfDynamicProxyClass, resourceClass, version, group); } @Override public Object getObject() throws Exception { return this.newInstance(); } @Override public Class<?> getObjectType() { return resourceClass; } @Override public boolean isSingleton() { return true; } public static Class<?> getProxyClass(Class<?> resourceClass) { /** * @see com.hjzgg.apigateway.dubbo.configure.SelfDubboAnnotationBean#postProcessAfterInitialization(Object, String) * @see org.springframework.aop.support.AopUtils#isAopProxy(Object) * @see org.springframework.aop.support.AopUtils#getTargetClass(Object) * @see com.hjzgg.apigateway.soa.proxy.provider.ProviderDynamicProxy#invoke(Object, Method, Object[]) * */ return Proxy.getProxyClass(ProviderProxyFactoryBean.class.getClassLoader(), new Class[]{resourceClass, SpringProxy.class, TargetClassAware.class}); } }
v5.3 动态代理适配器DynamicProxyAdapter
package com.hjzgg.apigateway.soa.proxy; import com.hjzgg.apigateway.soa.exceptions.SoaException; import org.springframework.util.ClassUtils; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @author hujunzheng * @create 2018-02-04 上午12:00 **/ public class DynamicProxyAdapter implements InvocationHandler { public DynamicProxyAdapter(ProxyFactoryBean factoryBean) { this.bean = factoryBean; } protected ProxyFactoryBean bean; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { throw new SoaException(String.format("%s %s %s", "你应当重写", ClassUtils.getQualifiedName(DynamicProxyAdapter.class), "invoke方法")); } public static Object createJDKProxy(ProxyFactoryBean factoryBean, Class<?> selfDynamicProxyClass) throws SoaException { if (!DynamicProxyAdapter.class.equals(selfDynamicProxyClass.getSuperclass())) { throw new SoaException(String.format("%s %s %s" , ClassUtils.getQualifiedName(selfDynamicProxyClass) , "需要继承" , ClassUtils.getQualifiedName(DynamicProxyAdapter.class) )); } Object selfDynamicProxyInstance; try { selfDynamicProxyInstance = selfDynamicProxyClass.getConstructor(factoryBean.getClass()).newInstance(factoryBean); } catch (Exception e) { throw new SoaException("500", "动态代理类创建失败", e); } Object proxy = Proxy.newProxyInstance(selfDynamicProxyClass.getClassLoader(), new Class[]{factoryBean.getResourceClass()}, (InvocationHandler) selfDynamicProxyInstance); return proxy; } }
v5.4 继承DynamicProxyAdapter 实现invoke接口 ProviderDynamicProxy
package com.hjzgg.apigateway.soa.proxy.provider; import com.hjzgg.apigateway.commons.utils.ContextUtils; import com.hjzgg.apigateway.soa.annotation.SOAImplements; import com.hjzgg.apigateway.soa.exceptions.SoaException; import com.hjzgg.apigateway.soa.proxy.DynamicProxyAdapter; import com.hjzgg.apigateway.soa.proxy.consumer.ConsumerProxyFactoryBean; import org.springframework.aop.TargetClassAware; import org.springframework.util.ClassUtils; import java.lang.reflect.Method; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; public class ProviderDynamicProxy extends DynamicProxyAdapter { private static final ConcurrentHashMap<Class<?>, Object> map = new ConcurrentHashMap<>(); public ProviderDynamicProxy(ProviderProxyFactoryBean factoryBean) { super(factoryBean); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { if (method.equals(TargetClassAware.class.getMethod("getTargetClass", new Class[]{}))) { return bean.getResourceClass(); } return method.invoke(this.findRelevantServiceProvider(), args); } catch (Exception e) { throw new SoaException("500", String.format("%s %s %s" , "invoke service proxy object error!" , ClassUtils.getQualifiedName(this.bean.getResourceClass()) , method.getName() ), e); } } private Object findRelevantServiceProvider() throws SoaException { Class<?> resourceClass = super.bean.getResourceClass(); if (!map.contains(resourceClass)) { Stream<?> stream = ContextUtils.getBeans(SOAImplements.class) .stream() .filter(serviceProvider -> resourceClass.isAssignableFrom(serviceProvider.getClass())); if (stream.count() > 1) { throw new SoaException(String.format( "multiple relevant service provider found with annotation %s and interface is %s" , ClassUtils.getQualifiedName(SOAImplements.class) , ClassUtils.getQualifiedName(resourceClass)) ); } if (stream.count() == 1) { map.put(resourceClass, stream.findFirst().get()); } else { List<?> objects = ContextUtils.getBeans(SOAImplements.class); if (objects.size() > 1) { throw new SoaException(String.format( "multiple relevant service provider found with annotation %s" , ClassUtils.getQualifiedName(SOAImplements.class)) ); } if (objects.size() == 1) { map.put(resourceClass, objects.get(0)); } else { try { Object object = ContextUtils.getBean(resourceClass); map.put(resourceClass, object); } catch (Exception e) { throw new SoaException("500", String.format( "find relevant service provider with interface %s error" , ClassUtils.getQualifiedName(resourceClass)), e ); } } } } return map.get(resourceClass); } }
v5.5 注册类型是jdk proxy类型的bean
//参数dynamicProxyClass 是 ProviderDynamicProxy
public static boolean registerProvider(BeanDefinitionRegistry registry, Class<?> dynamicProxyClass, Class<?> resourceClass) { String apiClassInfo = ClassUtils.getQualifiedName(resourceClass); try { /** * 通过代理bean的方式创建创建 服务bean * @see com.hjzgg.apigateway.dubbo.configure.SelfDubboAnnotationBean#postProcessAfterInitialization(Object, String) * if (AopUtils.isAopProxy(bean)), 判断bean的类型如果是代理类型,进行dubbo注解解析处理 * */ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(resourceClass); String dubboVersion = resourceClass.getAnnotation(Service.class).version(); String dubboGroup = resourceClass.getAnnotation(Service.class).group(); ProviderProxyFactoryBean providerProxyFactoryBean = new ProviderProxyFactoryBean(dynamicProxyClass, resourceClass, dubboVersion, dubboGroup); /** * providerProxyFactoryBean.getObject() 得到的是通过 Proxy.newInstance方法获取到的代理类 * @see com.hjzgg.apigateway.soa.proxy.DynamicProxyAdapter#createJDKProxy(ProxyFactoryBean, Class) * 可通过 Proxy.getInvocationHandler方法拿到 InvocationHandler实例 */ Class<?> targetProxyClass = ProviderProxyFactoryBean.getProxyClass(resourceClass); builder.addConstructorArgValue(Proxy.getInvocationHandler(providerProxyFactoryBean.getObject())); AbstractBeanDefinition beanDefinition = builder.getBeanDefinition(); beanDefinition.setBeanClass(targetProxyClass); beanDefinition.setAttribute(Constants.API_CLASS_INFO, resourceClass); String beanName = beanNameGenerator.generateBeanName(beanDefinition, registry); if (registry.containsBeanDefinition(beanName)) { log.debug(beanName + " already exists! Class is " + apiClassInfo + " ."); return false; } registry.registerBeanDefinition(beanName, beanDefinition); return true; } catch (Exception e) { log.error("registerProvider proxy bean error! Class is " + apiClassInfo + " ."); return false; } }
v5.6 附加SelfDubboAnnotationBean
View Code
v 5.7 附加AopUtils相关方法
/** * Check whether the given object is a JDK dynamic proxy or a CGLIB proxy. * <p>This method additionally checks if the given object is an instance * of {@link SpringProxy}. * @param object the object to check * @see #isJdkDynamicProxy * @see #isCglibProxy */ public static boolean isAopProxy(Object object) { return (object instanceof SpringProxy && (Proxy.isProxyClass(object.getClass()) || ClassUtils.isCglibProxyClass(object.getClass()))); } /** * Determine the target class of the given bean instance which might be an AOP proxy. * <p>Returns the target class for an AOP proxy or the plain class otherwise. * @param candidate the instance to check (might be an AOP proxy) * @return the target class (or the plain class of the given object as fallback; * never {@code null}) * @see org.springframework.aop.TargetClassAware#getTargetClass() * @see org.springframework.aop.framework.AopProxyUtils#ultimateTargetClass(Object) */ public static Class<?> getTargetClass(Object candidate) { Assert.notNull(candidate, "Candidate object must not be null"); Class<?> result = null; if (candidate instanceof TargetClassAware) { result = ((TargetClassAware) candidate).getTargetClass(); } if (result == null) { result = (isCglibProxy(candidate) ? candidate.getClass().getSuperclass() : candidate.getClass()); } return result; }
本文转自 小眼儿 博客园博客,原文链接:http://www.cnblogs.com/hujunzheng/p/8527338.html,如需转载请自行联系原作者