当前位置:网站首页>重写并自定义依赖的原生的Bean方法
重写并自定义依赖的原生的Bean方法
2022-07-30 11:02:00 【InfoQ】
前言
在项目开发过程中,往往是直接应用很多jar包中依赖且声明好的Bean,拿来即用,但很多场景也需要对这些原生的Bean 进行自定义,定制化封装,这样在项目使用的过程中,可以使用自定义的Bean,而不是原生的Bean。下面总结了几种定制化原生Bean 的几种方式:
- 在项目中创建同包同类名的类
这种方式使用较少,因为项目中的包路径根据开发规范是根据业务名自定义的包路径
2.使用 @Primary 注解,或 @Qualifier 注解,定义Bean 的优先级或使用时,指定Bean
@Primary 优先考虑,优先考虑被注解的对象注入@Qualifier 名字声明,声明后对名字进行使用 当一个类有多个Bean的实例时,可以在 Bean 的实现类中 使用 @Primary 注解声明Bean 的优先级,在使用过程中,spring则默认加载该类实例化出的Bean。而 @Qualifiler 注解先声明后使用,相当于多个实现起多个不同的名字,注入时候告诉我你要注入哪个;
@Primary 在源码中使用的示例: spring-cloud-starter-gateway 3.1.1 版本中的GatewayAutoConfiguration 中的源码
@Bean
@Primary
public RouteDefinitionLocator routeDefinitionLocator(List<RouteDefinitionLocator> routeDefinitionLocators) {
return new CompositeRouteDefinitionLocator(Flux.fromIterable(routeDefinitionLocators));
}@Qualiflier 注解使用,当一个类有多个Bean 实例时,在使用 Bean 时,通过 @Qualiflier 制定Bean
@Service("employeeserver")
public class EmployeeServiceImpl implements EmployeeService {
public EmployeeDto getEmployeeById(Long id) {
return new EmployeeDto();
}
}
@Service("manageserver")
public class ManagServiceImpl implements EmployeeService {
public ManagerDto getEmployeeById(Long id) {
return new ManagerDto();
}
}使用:
@Controller
@RequestMapping("/emplayee")
public class EmployeeInfoControl {
@Autowired
@Qualifier("employeeserver")
EmployeeService employeeService;
@RequestMapping(params = "method=showEmplayeeInfo")
public void showEmplayeeInfo(HttpServletRequest request, HttpServletResponse response){
***********************
*******************
}- 使用 @ComponentScan 里面的 excludeFilters 排除不需要加载的类
示例如下,排除 MyTestFilter 类
@SpringBootApplication
@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})})
public class TestApplication { ...
} 这里需要注意的是,可以定义一个与原生相同的Bean,但在 上面引包的时候,需要引入的包路径是要排除的包路径,这样自定义的相同的类就可以加载到容器中,原生的Bean 则不会加载。
这种方式也是常用的方式;
4.使用 @Bean 注解覆盖原生的Bean
该场景针对,框架jar包中有@ConditionalOnMissingBean注解,这种注解是说明如果你也创建了一个一样的Bean则框架就不自己再次创建这个bean了,这样你可以覆写自己的bean。
直接继承要覆盖的类,自己重写里面方法,使用@Component注入到 spring 中去:
package my.test.gateway.config;@Component
public class HttpClientFactory extends AbstractFactoryBean<HttpClient> {
protected final HttpClientProperties properties;
protected final ServerProperties serverProperties;
protected final List<HttpClientCustomizer> customizers;
public HttpClientFactory(HttpClientProperties properties, ServerProperties serverProperties, List<HttpClientCustomizer> customizers) {
this.properties = properties;
this.serverProperties = serverProperties;
this.customizers = customizers;
}
.....
}重新自定义 该类的方法为:直接继承要覆盖的类,自己重写里面方法,
使用@Component注入到spring中去
package my.test.gateway.config;@Component
public class HttpClientFactory extends AbstractFactoryBean<HttpClient> {
protected final HttpClientProperties properties;
protected final ServerProperties serverProperties;
protected final List<HttpClientCustomizer> customizers;
public HttpClientFactory(HttpClientProperties properties, ServerProperties serverProperties, List<HttpClientCustomizer> customizers) {
this.properties = properties;
this.serverProperties = serverProperties;
this.customizers = customizers;
}
.....
}5. 使用BeanDefinitionRegistryPostProcessor
使用 Spring 提供的 Bean 后置处理器,进行自定义的Bean 加载;
package com.mytest.config.beantest.register;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* @author amdin
*/
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
logger.info("bean 定义查看和修改...");
String beanName = "myTestService";
// 先移除原来的bean定义
beanDefinitionRegistry.removeBeanDefinition(beanName);
// 注册我们自己的bean定义
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(MyTestServiceIpml.class);
// 如果有构造函数参数, 有几个构造函数的参数就设置几个 没有就不用设置
beanDefinitionBuilder.addConstructorArgValue("构造参数1");
beanDefinitionBuilder.addConstructorArgValue("构造参数2");
beanDefinitionBuilder.addConstructorArgValue("构造参数3");
// 设置 init方法 没有就不用设置
beanDefinitionBuilder.setInitMethodName("init");
// 设置 destory方法 没有就不用设置
beanDefinitionBuilder.setDestroyMethodName("destory");
// 将Bean 的定义注册到Spring环境
beanDefinitionRegistry.registerBeanDefinition("myTestService", beanDefinitionBuilder.getBeanDefinition());
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
// bean的名字为key, bean的实例为value
Map<String, Object> beanMap = configurableListableBeanFactory.getBeansWithAnnotation(RestController.class);
logger.info("所有 RestController 的bean {}", beanMap);
}
}- 最常见的重写自定义Bean 的方式为以上的 2,3,4 三种方式,通过以上方式就可以实现重写并自定义原生的Bean
边栏推荐
- Neural Network Study Notes 4 - Autoencoder (including sparse, stacked) (updated)
- idea的package没有空心
- 类和对象—6个默认成员函数
- Beyond Stream Processing !第四届实时计算 Flink 挑战赛启动,49 万奖金等你来拿!
- 自定义查询--关于倒排索引的研究
- MySQL database maintenance
- RandLA-Net复现记录
- TensorFlow custom training function
- 【数据库基础】redis使用总结
- STM32F1 reads MLX90632 non-contact infrared temperature sensor
猜你喜欢
随机推荐
API 网关 APISIX 在Google Cloud T2A 和 T2D 的性能测试
Hu-cang integrated e-commerce project (1): project background and structure introduction
真正懂经营管理的CIO具备哪些特质
jmeter接口压力测试-(二)
salesforce使用方法(salesforce authenticator下载)
feign远程调用时如何在请求头加入数据
Log4j有哪几种日志级别呢?
【梦想起航】
RY-D1/1 Voltage Relay
vscode中写markdown格式笔记的配置过程和相关语法
MySQL之数据库维护
NLP领域的最新研究进展
ODrive应用 #4 配置参数&指令「建议收藏」
单片机开发之ADC0808/9信号采集
[ASP.NET Core] Dependency Injection for Option Classes
2022全球数字经济大会人工智能专场:AI安全受高度关注
ABP学习资源整理
AB test summary
【ASP.NET Core】选项类的依赖注入
Voltage relay HDY - vac - 1 A / 1-220









