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,如需转载请自行联系原作者