使用FactoryBean和动态代理 实现针对一个接口动态的在执行的时候 获取实现类
package extpoint;
public enum BizIdentityEnum {
QQ("123","qq"),
WEIXIN("456","weixin")
;
private String code;
private String name;
BizIdentityEnum(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package extpoint;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ExtPoint {
}
package extpoint;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ExtPointFactoryBean<T> implements FactoryBean<T>, ApplicationListener<ContextRefreshedEvent> {
//接口,所有业务身份的实现
private Map<String, List<ExtPonitWraper>> extPointMap=new HashMap<>();
//动态代理的接口名称
private String interfaceName;
@Override
public T getObject() throws Exception {
Class<?> clazz=Class.forName(interfaceName);
InvocationHandler invocationHandler=new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
List<ExtPonitWraper> extPonitWraperList=extPointMap.get(clazz.getName());
for(ExtPonitWraper extPonitWraper:extPonitWraperList){
BizIdentityEnum[] bizIdentityEnums= extPonitWraper.getBizIdentityEnum();
for(BizIdentityEnum bizIdentityEnum:bizIdentityEnums){
if(bizIdentityEnum.getCode().equals(args[0])){
Object result=method.invoke(extPonitWraper.getExtPoint(),args);
return result;
}
}
}
return null;
}
};
return (T)Proxy.newProxyInstance(ExtPointFactoryBean.class.getClassLoader(),new Class[]{clazz},invocationHandler);
}
@Override
public Class<?> getObjectType() {
try {
return Class.forName(interfaceName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
@Override
public boolean isSingleton() {
return true;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
ApplicationContext applicationContext=contextRefreshedEvent.getApplicationContext();
Map<String, Object> extPointImplMap= applicationContext.getBeansWithAnnotation(ExtPointImpl.class);
if(extPointImplMap!=null&&extPointImplMap.size()>0){
for(Object extPoint:extPointImplMap.values()){
Class<?> extPointClazz=extPoint.getClass();
ExtPointImpl extPointAnnotation=extPointClazz.getAnnotation(ExtPointImpl.class);
Class extPointClass=extPointAnnotation.value();
BizIdentityEnum[] bizIdentityEnums=extPointAnnotation.bizIdentity();
String extensionKey=extPointClass.getName();
ExtPonitWraper extPonitWraper=new ExtPonitWraper(extPoint,bizIdentityEnums);
List<ExtPonitWraper> extPonitWraperList=extPointMap.get(extensionKey);
if(CollectionUtils.isEmpty(extPonitWraperList)){
extPonitWraperList=new ArrayList<>();
}
extPonitWraperList.add(extPonitWraper);
extPointMap.put(extensionKey,extPonitWraperList);
}
}
}
public String getInterfaceName() {
return interfaceName;
}
public void setInterfaceName(String interfaceName) {
this.interfaceName = interfaceName;
}
}
package extpoint;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ExtPointImpl {
Class<?> value();
BizIdentityEnum[] bizIdentity();
}
package extpoint;
public class ExtPonitWraper<ExtPoint> {
ExtPoint extPoint;
BizIdentityEnum[] bizIdentityEnum;
public ExtPonitWraper(ExtPoint extPoint, BizIdentityEnum[] bizIdentityEnum) {
this.extPoint = extPoint;
this.bizIdentityEnum = bizIdentityEnum;
}
public ExtPoint getExtPoint() {
return extPoint;
}
public void setExtPoint(ExtPoint extPoint) {
this.extPoint = extPoint;
}
public BizIdentityEnum[] getBizIdentityEnum() {
return bizIdentityEnum;
}
public void setBizIdentityEnum(BizIdentityEnum[] bizIdentityEnum) {
this.bizIdentityEnum = bizIdentityEnum;
}
}
package extpoint;
import extpoint.item.ItemExtPoint;
public class BuyItemTest {
private ItemExtPoint itemExtPoint;
public void buyItem(){
System.out.println(itemExtPoint.getItemName());
}
public ItemExtPoint getItemExtPoint() {
return itemExtPoint;
}
public void setItemExtPoint(ItemExtPoint itemExtPoint) {
this.itemExtPoint = itemExtPoint;
}
}
package extpoint.item;
import extpoint.ExtPoint;
@ExtPoint
public interface ItemExtPoint {
String getItemName();
}
package extpoint.item;
import extpoint.BizIdentityEnum;
import extpoint.ExtPoint;
import extpoint.ExtPointImpl;
@ExtPointImpl(value = ItemExtPoint.class,bizIdentity = {BizIdentityEnum.QQ})
public class QQItemExtPointImpl implements ItemExtPoint {
@Override
public String getItemName() {
return "qqItemName";
}
}
package extpoint.item;
import extpoint.BizIdentityEnum;
import extpoint.ExtPointImpl;
@ExtPointImpl(value = ItemExtPoint.class,bizIdentity = {BizIdentityEnum.WEIXIN})
public class WeixinItemExtPointImpl implements ItemExtPoint {
@Override
public String getItemName() {
return "weixinItemName";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="itemExtPoint" class="extpoint.ExtPointFactoryBean">
<property name="interfaceName" value="extpoint.item.ItemExtPoint"/>
</bean>
<bean id="qqItemExtPoint" class="extpoint.item.QQItemExtPointImpl"></bean>
<bean id="weixinItemExtPoint" class="extpoint.item.WeixinItemExtPointImpl"></bean>
</beans>
版权声明:本文为u011955252原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。