内容简介:翻译自:https://stackoverflow.com/questions/47360476/spring-programmatic-bean-autowired-as-proxy-instead-of-target
我创建了一个注释,用于创建使用环境中的值填充的ThreadPoolTaskExecutors.但是,当我自动装配bean时,它给了我一个代理并调用代理上的方法给出了错误的值.
如果我手动访问目标类,那么我会得到正确的值.
Executor exec = (Executor) ((Advised) executor).getTargetSource().getTarget(); ThreadPoolTaskExecutor taskExec = (ThreadPoolTaskExecutor) exec;
我一直在摸不着头脑,为什么我得到了一个代理bean,但似乎无法弄明白.
我正在使用注释导入我的注册器类,该类实现ImportBeanDefinitionRegistrar来注册bean.注册商代码如下:
public class ExecutorEnumerationRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware { public static final String CORE_POOL_SIZE = "corePoolSize"; public static final String MAX_POOL_SIZE = "maxPoolSize"; public static final String QUEUE_CAPACITY = "queueCapacity"; public static final String THREAD_NAME_PREFIX = "threadNamePrefix"; private static final String REJECTED_EXECUTION_HANDLER = "rejectedExecutionHandler"; private static final String NAMES = "names"; private static final String REJECTED_HANDLER = "rejectedHandler"; private Environment env; @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { Map<String, Object> attrs = importingClassMetadata.getAnnotationAttributes(ThreadPoolTaskExecutorCreator.class.getName(), true); final String[] beanNames = (String[]) attrs.get(NAMES); final String[] policyClass = (String[]) attrs.get(REJECTED_HANDLER); for (int x = 0; x < beanNames.length; x++) { createAndRegisterBean(beanNames[x], policyClass[x], registry); } } private void createAndRegisterBean(String name, String policyClass, BeanDefinitionRegistry registry) { GenericBeanDefinition bd = new GenericBeanDefinition(); bd.setBeanClass(ThreadPoolTaskExecutor.class); bd.setAutowireCandidate(true); bd.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); MutablePropertyValues mpv = bd.getPropertyValues(); populateProperties(mpv, name, policyClass); registry.registerBeanDefinition(name, bd); } private void populateProperties(MutablePropertyValues mpv, String name, String policyClass) { mpv.add(CORE_POOL_SIZE, Integer.valueOf(env.getProperty(name + "." + CORE_POOL_SIZE))); mpv.add(MAX_POOL_SIZE, Integer.valueOf(env.getProperty(name + "." + MAX_POOL_SIZE))); mpv.add(QUEUE_CAPACITY, Integer.valueOf(env.getProperty(name + "." + QUEUE_CAPACITY))); try { mpv.add(REJECTED_EXECUTION_HANDLER, Class.forName(policyClass).newInstance()); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { e.printStackTrace(); } mpv.add(THREAD_NAME_PREFIX, name + "-"); } @Override public void setEnvironment(Environment environment) { env = environment; } }
导入注册商的注释:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Import(ExecutorEnumerationRegistrar.class) public @interface ThreadPoolTaskExecutorCreator{ String[] names(); String[] rejectedHandler() default ThreadPoolPolicyHandlers.CALLER_RUNS_POLICY; }
我已经使用以下代码进行了测试:
Spring Boot类:
@EnableDiscoveryClient @ComponentScan("my.test.classes") @ThreadPoolTaskExecutorCreator(names = {"testExecutor"}, rejectedHandler = ThreadPoolPolicyHandlers.DISCARD_POLICY) @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, SessionAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class, JndiDataSourceAutoConfiguration.class, JndiConnectionFactoryAutoConfiguration.class, RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class}) public class TestBoot { public static void main(String[] args) { SpringApplication.run(TestBoot.class, args); } }
spring-boot-starter-parent 1.4.5.RELEASE的所有版本
我写了一个JUnit测试,检查值并通过.它唯一不起作用的是我在Spring Boot eureka应用程序中自动装配它.有什么我可以这样做,它不会自动装配代理bean?我搜索了文档并查看了所有相关的类,但我没有看到任何与它为代理相关的内容.另外,为什么在通过代理访问时会给出错误的值?
似乎您缺少用于注册ImportBeanDefinitionRegistrar实例的代码(在您的示例中为ExecutorEnumerationRegistrar)
因此,有两种方法可以注册ImportBeanDefinitionRegistrar直接使用@Import注释或实现ImportSelector接口,它可以为您提供更多通用配置选项.
对于您的情况,只需在Configuration类上添加@Import({ExecutorEnumerationRegistrar.class})即可.
@EnableDiscoveryClient @ComponentScan("my.test.classes") @ThreadPoolTaskExecutorCreator(names = {"testExecutor"}, rejectedHandler = ThreadPoolPolicyHandlers.DISCARD_POLICY) // THIS IS REQUIRED @Import({ExecutorEnumerationRegistrar.class}) // See Above @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, SessionAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class, JndiDataSourceAutoConfiguration.class, JndiConnectionFactoryAutoConfiguration.class, RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class}) public class TestBoot { public static void main(String[] args) { SpringApplication.run(TestBoot.class, args); } }
并且只需记住在自动装配ThreadPoolTaskExecutor实例时使用@Qualifier.参见示例组件
@Component public class Component { @Autowired @Qualifier("testExecutor") private ThreadPoolTaskExecutor exec; // you methods }
翻译自:https://stackoverflow.com/questions/47360476/spring-programmatic-bean-autowired-as-proxy-instead-of-target
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- NIPS 2018:作为多目标优化的多任务学习:寻找帕累托最优解
- 华为汽车中自动驾驶目标检测怎么理解?(通过跨模式的雷达目标检测)
- 使用Elasticsearch作为主数据存储
- 如何把MongoDB作为循环队列
- 使用 utterances 作为博客评论组件
- 作为项目经理应该串联起哪些流程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Big Java Late Objects
Horstmann, Cay S. / 2012-2 / 896.00元
The introductory programming course is difficult. Many students fail to succeed or have trouble in the course because they don't understand the material and do not practice programming sufficiently. ......一起来看看 《Big Java Late Objects》 这本书的介绍吧!