如何把接口加入到Spring容器(任何类/接口都可以用这个方式,例如动态代理)

问题缘由

起因是设计一款RPC框架,但是客户端由于只有接口,没有实现,所以加入Spring不能实现。因此和分享小组成员讨论研究,最后得到自己想要的是什么。

gitee地址:https://gitee.com/kylin1991_admin/rpc_handwriting

快速开始

1、加入maven包
  • 加入jarreflections-可以选择不加入,我只是为了扫包方便(后面可以自己写扫描)

        <!-- https://mvnrepository.com/artifact/org.reflections/reflections -->
        <dependency>
          <groupId>org.reflections</groupId>
          <artifactId>reflections</artifactId>
          <version>0.9.11</version>
          <exclusions>
            <exclusion>
              <groupId>javassist</groupId>
              <artifactId>javassist</artifactId>
            </exclusion>
          </exclusions>
        </dependency>
    
  • Spring-context 这个需要的,因为我们要用容器和注解和bean

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>5.2.4.RELEASE</version>
        </dependency>
    
2、写一个自己的FactoryBean
  • 例如:我是要实现动态代理,自己写了一个

    public class FactoryRpcClientBean<T> implements FactoryBean<T> {
        private Class<T> interfaceType;
        private String host;
        private int port;
    
        public FactoryRpcClientBean(Class<T> interfaceType, String host, int port) {
            // 构造器的参数可以自己定义,
            // 只需要在beanDefinition注册的时候传递过来即可
            this.interfaceType = interfaceType;
            this.host = host;
            this.port = port;
        }
    
        @Override
        public T getObject() throws Exception {
            // 这里主要是创建接口对应的实例,便于注入到spring容器中
            // 所以这里也是控制实例的结果的。
            return new RpcProxyClient().proxyClient(interfaceType, host, port);
        }
    
        @Override
        public Class<T> getObjectType() {
            // 这里是控制类型,同时也可以根据这个类型来获取bean
            return interfaceType;
        }
    
        @Override
        public boolean isSingleton() {
            return true;
        }
    }
    
3、干预BeanDefinition
  • 只需要注意bean的注册和需要什么参数就行了,其他忽略(是我个人的框架需要而已)

    @Configuration
    public class SpringConfig implements BeanDefinitionRegistryPostProcessor {
    
        private static final String host = "localhost";
        private static final int port = 8080;
        private static final String SCANNER_PATH = "org.example";
    
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
    
            // 扫描xx路径下的@注解的接口或类
            Reflections reflections = new Reflections(SCANNER_PATH);
            Set<Class<?>> set = reflections.getTypesAnnotatedWith(RpcClient.class);
            for (Class<?> aClass : set) {
    
                // 通过FactoryRpcClientBean来生成一个新的BeanDefinition
                BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(FactoryRpcClientBean.class);
                BeanDefinition definition =builder.getRawBeanDefinition();
    
                // 传入构造参数
                definition.getConstructorArgumentValues().addGenericArgumentValue(aClass);
     			definition.getConstructorArgumentValues().addGenericArgumentValue(host);
     			definition.getConstructorArgumentValues().addGenericArgumentValue(port);
    
                // 注册BeanDefinitionBuilder
                beanDefinitionRegistry.registerBeanDefinition(aClass.getSimpleName(), definition);
            }
        }
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    
        }
    }
    

上面已经完成,可以直接使用了

下面就是加入自己的注解,不过和上面没多大关系了

1、自定义Autowired注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Autowired
public @interface RpcClient {
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值