[英]How to inject Spring boot Environment bean to Custom Spring xml bean?
[英]Spring Boot Custom Bean Loader
我將 JDBI 與 Spring 引導一起使用。 我遵循了這個指南,這導致必須創建一個 class: JdbiConfig
在其中,對於應用程序上下文中需要的每個 dao,您必須添加:
@Bean
public SomeDao someDao(Jdbi jdbi) {
return jdbi.onDemand(SomeDao.class);
}
我想知道 Spring Boot 中是否有某種方法可以創建自定義處理器來創建 bean 並將它們放入應用程序上下文中。 我對這如何工作有兩個想法:
@JdbiDao
對 DAO 進行注解,然后編寫一些內容來獲取它們。 我已經嘗試將這些手動注入到應用程序啟動中,但問題是它們可能無法及時加載以注入,因為在 class 掃描期間無法識別它們。JdbiDao
。 然后使用標准的@Repository
注釋接口並創建一個自定義處理器以通過Jdbi#onDemand
加載它們這是我的兩個想法,但我不知道有什么方法可以實現。 我堅持手動創建一個bean? 這個問題以前解決過嗎?
策略是掃描您的類路徑以查找 dao 接口,然后將它們注冊為 bean。
我們需要: BeanDefinitionRegistryPostProcessor來注冊額外的 bean 定義和FactoryBean來創建 jdbi dao bean 實例。
@JdbiDao
標記你的 dao 接口@JdbiDao
public interface SomeDao {
}
FactoryBean
來創建jdbi daopublic class JdbiDaoBeanFactory implements FactoryBean<Object>, InitializingBean {
private final Jdbi jdbi;
private final Class<?> jdbiDaoClass;
private volatile Object jdbiDaoBean;
public JdbiDaoBeanFactory(Jdbi jdbi, Class<?> jdbiDaoClass) {
this.jdbi = jdbi;
this.jdbiDaoClass = jdbiDaoClass;
}
@Override
public Object getObject() throws Exception {
return jdbiDaoBean;
}
@Override
public Class<?> getObjectType() {
return jdbiDaoClass;
}
@Override
public void afterPropertiesSet() throws Exception {
jdbiDaoBean = jdbi.onDemand(jdbiDaoClass);
}
}
@JdbiDao
注釋接口的類路徑:public class JdbiBeanFactoryPostProcessor
implements BeanDefinitionRegistryPostProcessor, ResourceLoaderAware, EnvironmentAware, BeanClassLoaderAware, BeanFactoryAware {
private BeanFactory beanFactory;
private ResourceLoader resourceLoader;
private Environment environment;
private ClassLoader classLoader;
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false) {
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
// By default, scanner does not accept regular interface without @Lookup method, bypass this
return true;
}
};
scanner.setEnvironment(environment);
scanner.setResourceLoader(resourceLoader);
scanner.addIncludeFilter(new AnnotationTypeFilter(JdbiDao.class));
List<String> basePackages = AutoConfigurationPackages.get(beanFactory);
basePackages.stream()
.map(scanner::findCandidateComponents)
.flatMap(Collection::stream)
.forEach(bd -> registerJdbiDaoBeanFactory(registry, bd));
}
private void registerJdbiDaoBeanFactory(BeanDefinitionRegistry registry, BeanDefinition bd) {
GenericBeanDefinition beanDefinition = (GenericBeanDefinition) bd;
Class<?> jdbiDaoClass;
try {
jdbiDaoClass = beanDefinition.resolveBeanClass(classLoader);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
beanDefinition.setBeanClass(JdbiDaoBeanFactory.class);
// Add dependency to your `Jdbi` bean by name
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("jdbi"));
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(Objects.requireNonNull(jdbiDaoClass));
registry.registerBeanDefinition(jdbiDaoClass.getName(), beanDefinition);
}
}
JdbiBeanFactoryPostProcessor
@SpringBootApplication
@Import(JdbiBeanFactoryPostProcessor.class)
public class Application {
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.