私は、環境から値を取り込んだThreadPoolTaskExecutorsを作成するためのアノテーションを作成しました。しかし、私がBeanをオートワイヤすると、私にプロキシが与えられ、プロキシのメソッドを呼び出すと間違った値が返されます。ターゲットではなくプロキシとしてオートプログラムされたSpringのプログラムビーン
ターゲットクラスに手動でアクセスすると、正しい値が得られます。
Executor exec = (Executor) ((Advised) executor).getTargetSource().getTarget();
ThreadPoolTaskExecutor taskExec = (ThreadPoolTaskExecutor) exec;
私は、プロキシBeanを取得しています理由として、今しばらくの間、私の頭を悩まされているが、それを把握するように見えることはできません。
私は、Beanを登録するためにImportBeanDefinitionRegistrarを実装するレジストラクラスをインポートするために注釈を使用しています。レジストラのコードは以下の通りです:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(ExecutorEnumerationRegistrar.class)
public @interface ThreadPoolTaskExecutorCreator{
String[] names();
String[] rejectedHandler() default ThreadPoolPolicyHandlers.CALLER_RUNS_POLICY;
}
私は次のコードでテストされています: 春ブーツクラス:春から
@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);
}
}
すべてのバージョン
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;
}
}
注釈がレジストラをインポートします-boot-starter-parent 1.4.5.RELEASE
私はJUnitテストを作成しました。それは値をチェックし、それがパスします。 それがうまくいけないのは、私がSpring Boot eurekaアプリケーションでautowireするときだけです。私はそれがプロキシビーンをautowireしないように何かできますか?私はドキュメンテーションを検索し、関連するすべてのクラスを見てきましたが、なぜそれがプロキシであるかに関係するものは何も表示されません。また、プロキシ経由でアクセスすると、なぜ不正な値を返すのでしょうか?
"それは不正確な値を与える"とはどういう意味ですか?あなたのコードで 'ThreadPoolTaskExecutor'の注入と使用のためのコードを共有できますか? – Babl
私は単に他の春の豆でそれをautowiringしています。私は、コアプールサイズ、最大プールサイズ、およびキュー容量の値を表示しています。作成時に送信されるプロパティではなく、デフォルト値が返されます。 –
あなたのコードが私にとって完璧にうまくいくように私は尋ねています:)あなたは少なくともSpring/Spring Bootのバージョンを共有することができますか? – Babl