开发者社区> 问答> 正文

为什么直接创建一个对象可以注册到spring,动态代理的对象不可以注册到spring??报错

## 问题:
我分别通过直接new对象,与动态代理生成代理对象加载到spring,并获取bean,
当注册直接new对象正常,而动态代理对象报错:

```
Initialization of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testApiService': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.reflect.InvocationHandler' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
```
## 代码:


```
@Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        System.out.println("--------------------------------------------");
        String name = "testApiService";
        Object proxyB = (TestApi) () -> {
            System.out.println("------new :↓------");
            return "new Object: hello";
        };
        Class<?> interfaceClass = TestApi.class;
        XHGAProxy xhgaProxy = new XHGAProxy<>(interfaceClass, proxyB);
        // 代理对象------->不能注册到spring
        Object proxyA = Proxy.newProxyInstance(interfaceClass.getClassLoader(),
                new Class[]{interfaceClass}, xhgaProxy);
        TestApi testApiA = (TestApi) proxyA;
        System.out.println("动态代理:" + testApiA.sayHello());
        // new的抽象对象-->可以注册到spring
        TestApi testApiB = (TestApi) proxyB;
        System.out.println("new 对象:" + testApiB.sayHello());
        ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
        DefaultListableBeanFactory beanFactory =
                (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();
        BeanDefinitionBuilder beanDefinitionBuilder =
                BeanDefinitionBuilder.genericBeanDefinition(proxyA.getClass());
        //beanFactory.removeBeanDefinition(name);
        // 注册
        beanFactory.registerBeanDefinition(name, beanDefinitionBuilder.getRawBeanDefinition());
        // 获取加载到spring的bean
        Object bean = applicationContext.getBean(name);
        System.out.println(bean);
    }
```

展开
收起
爱吃鱼的程序员 2020-06-06 09:27:56 598 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB
                        <p>已解决:</p> 
    
    //-------↓添加以下代码
    beanDefinitionBuilder.addConstructorArgValue(Proxy.getInvocationHandler(proxyA));
    AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
    beanDefinition.setBeanClass(proxyA.getClass());
    //-------↑
                        <p>完整代码:</p> 
    
    @Component
    public class XHGAProxyScan2 implements ApplicationContextAware,InitializingBean {
        ApplicationContext applicationContext;
        @Override
        public void afterPropertiesSet() throws Exception { }
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
            String name = "testApiService";
            Object proxyB = (TestApi) () -> {
                System.out.println("------new :↓------");
                return "new Object: hello";
            };
            Class<?> interfaceClass = TestApi.class;
            XHGAProxy xhgaProxy = new XHGAProxy<>(interfaceClass, proxyB);
            Object proxyA = Proxy.newProxyInstance(interfaceClass.getClassLoader(),
                    new Class[]{interfaceClass}, xhgaProxy);
            System.out.println("代理Object:" + proxyA);
            TestApi testApiA = (TestApi) proxyA;
            System.out.println("动态代理:" + testApiA.sayHello());
            // new的抽象对象-->可以注册到spring
            TestApi testApiB = (TestApi) proxyB;
            System.out.println("new 对象:" + testApiB.sayHello());
            ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
            DefaultListableBeanFactory beanFactory =
                    (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();
            BeanDefinitionBuilder beanDefinitionBuilder =
                    BeanDefinitionBuilder.genericBeanDefinition(proxyA.getClass());
            //-------↓添加以下代码
            beanDefinitionBuilder.addConstructorArgValue(Proxy.getInvocationHandler(proxyA));
            AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
            beanDefinition.setBeanClass(proxyA.getClass());
            //-------↑
            beanFactory.registerBeanDefinition(name, beanDefinitionBuilder.getRawBeanDefinition());
        }
    2020-06-06 09:28:08
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧 立即下载
微服务架构模式与原理Spring Cloud开发实战 立即下载
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载