如何实现扩展点方案一

  • Post author:
  • Post category:其他

使用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 版权协议,转载请附上原文出处链接和本声明。