后端开发速查:必备的Spring IOC 容器底层注解使用【完整版】(下)

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 后端开发速查:必备的Spring IOC 容器底层注解使用【完整版】(下)

六、Bean的初始化方法和销毁方法.

  • ①:什么是bean的生命周期?

bean的创建----->初始化----->销毁方法

由容器管理Bean的生命周期,我们可以通过自己指定bean的初始化方法和bean的销毁方法

@Configuration
public class MainConfig {
//指定了bean的生命周期的初始化方法和销毁方法.
@Bean(initMethod = "init",destroyMethod = "destroy")
public Car car() {
return new Car();
}
}

针对单实例bean的话,容器启动的时候,bean的对象就创建了,而且容器销毁的时候,也会调用Bean的销毁方法针对多实例bean的话,容器启动的时候,bean是不会被创建的而是在获取bean的时候被创建,而且bean的销毁不受IOC容器的管理.


②:通过 InitializingBean和DisposableBean 的二个接口实现bean的初始化以及销毁方法

@Component
public class Person implements InitializingBean,DisposableBean {
public Person() {
System.out.println("Person的构造方法");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean的destroy()方法 ");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean的 afterPropertiesSet方法");
}
}
  • ③:通过JSR250规范 提供的注解@PostConstruct 和@ProDestory标注的方法
@Component
public class Book {
public Book() {
System.out.println("book 的构造方法");
}
@PostConstruct
public void init() {
System.out.println("book 的PostConstruct标志的方法");
}
@PreDestroy
public void destory() {
System.out.println("book 的PreDestory标注的方法");
}
}


④:通过Spring的BeanPostProcessor的 bean的后置处理器会拦截所有bean创建过程

postProcessBeforeInitialization 在init方法之前调用

**postProcessAfterInitialization 在init方法之后调用

@Component
public class TaoRenBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("TaoRenBeanPostProcessor...postProcessBeforeInitialization:"+beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("TaoRenBeanPostProcessor...postProcessAfterInitialization:"+beanName);
return bean;
}
}


BeanPostProcessor的执行时机

populateBean(beanName, mbd, instanceWrapper)
initializeBean{
applyBeanPostProcessorsBeforeInitialization()
invokeInitMethods{
isInitializingBean.afterPropertiesSet
自定义的init方法
}
applyBeanPostProcessorsAfterInitialization()方法
}


七、通过@Value +@PropertySource来给组件赋值

public class Person {
//通过普通的方式
@Value("司马")
private String firstName;
//spel方式来赋值
@Value("#{28-8}")
private Integer age;
通过读取外部配置文件的值
@Value("${person.lastName}")
private String lastName;
}
@Configuration
@PropertySource(value = {"classpath:person.properties"}) //指定外部文件的位置
public class MainConfig {
@Bean
public Person person() {
return new Person();
}
}


八、自动装配 @AutoWired的使用

自动注入:

//一个Dao
@Repository
public class TaoRenDao {
}
@Service
public class TaoRenService {
@Autowired
private TaoRenDao TaoRenDao;


结论:

a:自动装配首先时按照类型进行装配,若在IOC容器中发现了多个相同类型的组件,那么就按照 属性名称来进行装配

@Autowired

private TaoRenDao TaoRenDao;

比如,我容器中有二个TaoRenDao类型的组件 一个叫TaoRenDao 一个叫TaoRenDao2

那么我们通过@AutoWired 来修饰的属性名称时TaoRenDao,那么拿就加载容器的TaoRenDao组件,若属性名称为

tulignDao2 那么他就加载的时TaoRenDao2组件

b:假设我们需要指定特定的组件来进行装配,我们可以通过使用@Qualifier(“TaoRenDao”)来指定装配的组件

或者在配置类上的@Bean加上@Primary注解

@Autowired
@Qualifier("TaoRenDao")
private TaoRenDao TaoRenDao2;


c:假设我们容器中即没有TaoRenDao 和TaoRenDao2,那么在装配的时候就会抛出异常

No qualifying bean of type ‘com.TaoRen.testautowired.TaoRenDao’ available

若我们想不抛异常 ,我们需要指定 required为false的时候可以了

@Autowired(required = false)
@Qualifier("TaoRenDao")
private TaoRenDao TaoRenDao2;
  • d:@Resource(JSR250规范)
    功能和@AutoWired的功能差不多一样,但是不支持@Primary 和@Qualifier的支持
  • e:@InJect(JSR330规范)
    需要导入jar包依赖功能和支持@Primary功能 ,但是没有Require=false的功能
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>

f:使用autowired 可以标注在方法上标注在set方法上

//@Autowired
public void setTaoRenLog(TaoRenLog TaoRenLog) {
this.TaoRenLog = TaoRenLog;
}


标注在构造方法上

@Autowired
public TaoRenAspect(TaoRenLog TaoRenLog) {
this.TaoRenLog = TaoRenLog;
}


标注在配置类上的入参中(可以不写)

@Bean
public TaoRenAspect TaoRenAspect(@Autowired TaoRenLog TaoRenLog) {
TaoRenAspect TaoRenAspect = new TaoRenAspect(TaoRenLog);
return TaoRenAspect;
}


九、自定义组件

我们自己的组件时,需要使用spring ioc的底层组件的时候,比如 ApplicationContext等.我们可以通过实现XXXAware接口来实现

@Component
public class TaoRenCompent implements ApplicationContextAware,BeanNameAware {
private ApplicationContext applicationContext;
@Override
public void setBeanName(String name) {
System.out.println("current bean name is :【"+name+"】");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}


十、@Profile注解指定环境

过@Profile注解来根据环境来激活标识不同的Bean@Profile标识在类上,那么只有当前环境匹配,整个配置类才会生效@Profile标识在Bean上 ,那么只有当前环境的Bean才会被激活没有标志为@Profile的bean 不管在什么环境都可以被激活.

@Configuration
@PropertySource(value = {"classpath:ds.properties"})
public class MainConfig implements EmbeddedValueResolverAware {
@Value("${ds.username}")
private String userName;
@Value("${ds.password}")
private String password;
private String jdbcUrl;
private String classDriver;
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.jdbcUrl = resolver.resolveStringValue("${ds.jdbcUrl}");
this.classDriver = resolver.resolveStringValue("${ds.classDriver}");
}
//标识为测试环境才会被装配
@Bean
@Profile(value = "test")
public DataSource testDs() {
return buliderDataSource(new DruidDataSource());
}
//标识开发环境才会被激活
@Bean
@Profile(value = "dev")
public DataSource devDs() {
return buliderDataSource(new DruidDataSource());
}
//标识生产环境才会被激活
@Bean
@Profile(value = "prod")
public DataSource prodDs() {
return buliderDataSource(new DruidDataSource());
}
private DataSource buliderDataSource(DruidDataSource dataSource) {
dataSource.setUsername(userName);
dataSource.setPassword(password);
dataSource.setDriverClassName(classDriver);
dataSource.setUrl(jdbcUrl);
return dataSource;
}
}


激活切换环境的方法

  • 方法一:通过运行时jvm参数来切换 -Dspring.profiles.active=test|dev|prod
  • 方法二:通过代码的方式来激活
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("test","dev");
ctx.register(MainConfig.class);
ctx.refresh();
printBeanName(ctx);
}


相关文章
|
3天前
|
API 持续交付 开发者
构建高效微服务架构:后端开发的新视角
【5月更文挑战第8天】 随着现代软件开发的演变,微服务架构已经成为了企业追求敏捷、可扩展和灵活部署的重要解决方案。本文将深入探讨如何构建一个高效的微服务架构,包括关键的设计原则、技术栈选择以及持续集成与部署的最佳实践。我们还将讨论微服务带来的挑战,如数据一致性、服务发现和网络延迟,并提出相应的解决策略。通过本文,后端开发者将获得构建和维护微服务系统所需的深度知识,并了解如何在不断变化的技术环境中保持系统的健壮性和可维护性。
35 8
|
2天前
|
存储 监控 API
构建高效微服务架构:后端开发的现代实践
【5月更文挑战第9天】 在本文中,我们将深入探讨如何在后端开发中构建一个高效的微服务架构。通过分析不同的设计模式和最佳实践,我们将展示如何提升系统的可扩展性、弹性和维护性。我们还将讨论微服务架构在处理复杂业务逻辑和高并发场景下的优势。最后,我们将分享一些实用的工具和技术,以帮助开发者实现这一目标。
|
2天前
|
前端开发 安全 Java
使用Spring框架加速Java开发
使用Spring框架加速Java开发
5 0
|
3天前
|
Kubernetes 持续交付 开发者
构建高效微服务架构:后端开发的新趋势
【5月更文挑战第8天】 随着现代软件开发的不断演进,微服务架构已成为众多企业解决复杂系统问题的首选方案。本文深入探讨了微服务架构的核心概念、设计原则以及实施策略,旨在为后端开发者提供一种清晰、高效的技术路径。通过分析微服务的优势与挑战,结合具体的应用实例,文章将展示如何通过容器化、服务网格和持续集成/持续部署(CI/CD)等先进技术手段,实现后端服务的高可用性、可扩展性和敏捷性。
|
3天前
|
消息中间件 监控 Java
构建高效微服务架构:后端开发的新趋势
【5月更文挑战第8天】随着现代软件开发的复杂性日益增加,传统的单体应用架构逐渐难以满足快速迭代和灵活部署的需求。微服务架构作为一种新的解决方案,以其模块化、独立性强和易于扩展的特点,正在成为后端开发领域的重要趋势。本文将深入探讨如何构建一个高效的微服务架构,并分析其对后端开发实践的影响。
|
3天前
|
敏捷开发 持续交付 API
构建高效微服务架构:后端开发的现代实践
【5月更文挑战第8天】 在数字化转型的浪潮中,微服务架构已成为企业追求敏捷开发、持续交付和系统弹性的关键解决方案。本文将深入探讨微服务的核心概念,包括其设计原则、优缺点以及如何在后端开发中实现高效的微服务架构。我们将通过实际案例分析,展示微服务如何帮助企业快速适应市场变化,同时保持系统的可维护性和扩展性。
|
4天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
45 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
4天前
|
设计模式 Kubernetes 数据库
构建高效可靠的微服务架构:后端开发的新范式
【5月更文挑战第7天】在现代软件开发的浪潮中,微服务架构已经成为一种流行的设计模式。它通过将应用程序分解为一组小的、独立的服务来提高系统的可维护性和扩展性。本文深入探讨了微服务架构的核心概念、优势以及如何利用最新的后端技术构建一个高效且可靠的微服务体系。我们将讨论关键的设计原则,包括服务的独立性、通信机制、数据一致性和容错性,并展示如何在云环境中部署和管理这些服务。
17 3
|
5天前
|
机器学习/深度学习 存储 人工智能
未来趋势:后端开发的新纪元
随着科技的不断进步,后端开发领域也在不断演进。本文将探讨未来后端开发的新趋势,包括分布式系统、云原生技术、微服务架构以及人工智能在后端开发中的应用。通过深入分析这些趋势,我们可以更好地了解未来后端开发的发展方向,为技术人员提供指导和启示。
16 2
|
5天前
|
缓存 监控 数据库
构建高性能微服务架构:后端开发的终极指南
【5月更文挑战第6天】 在现代软件开发的浪潮中,微服务架构以其灵活性、可扩展性和容错性引领着技术潮流。本文深入探索了构建高性能微服务架构的关键要素,从服务划分原则到通信机制,再到持续集成和部署策略。我们将透过实战案例,揭示如何优化数据库设计、缓存策略及服务监控,以确保系统的稳定性和高效运行。文中不仅分享了最佳实践,还讨论了常见的陷阱与解决之道,为后端开发者提供了一条清晰、可行的技术路径。