后端开发速查:必备的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);
}


相关文章
|
27天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
48 0
|
1月前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
58 4
SpringBoot必须掌握的常用注解!
|
12天前
|
前端开发 Java Spring
探索Spring MVC:@Controller注解的全面解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序的基石之一。它不仅简化了控制器的定义,还提供了一种优雅的方式来处理HTTP请求。本文将全面解析`@Controller`注解,包括其定义、用法、以及在Spring MVC中的作用。
29 2
|
24天前
|
缓存 监控 开发者
掌握Docker容器化技术:提升开发效率的利器
在现代软件开发中,Docker容器化技术成为提升开发效率和应用部署灵活性的重要工具。本文介绍Docker的基本概念,并分享Dockerfile最佳实践、容器网络配置、环境变量和秘密管理、容器监控与日志管理、Docker Compose以及CI/CD集成等技巧,帮助开发者更高效地利用Docker。
|
1月前
|
存储 安全 Java
springboot当中ConfigurationProperties注解作用跟数据库存入有啥区别
`@ConfigurationProperties`注解和数据库存储配置信息各有优劣,适用于不同的应用场景。`@ConfigurationProperties`提供了类型安全和模块化的配置管理方式,适合静态和简单配置。而数据库存储配置信息提供了动态更新和集中管理的能力,适合需要频繁变化和集中管理的配置需求。在实际项目中,可以根据具体需求选择合适的配置管理方式,或者结合使用这两种方式,实现灵活高效的配置管理。
17 0
|
4月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
6月前
|
XML Java 数据格式
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
47 1
|
3月前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
239 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
6月前
|
XML druid Java
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
65 0
|
4月前
|
XML Java 数据格式
Spring5入门到实战------3、IOC容器-Bean管理XML方式(一)
这篇文章详细介绍了Spring框架中IOC容器的Bean管理,特别是基于XML配置方式的实现。文章涵盖了Bean的定义、属性注入、使用set方法和构造函数注入,以及如何注入不同类型的属性,包括null值、特殊字符和外部bean。此外,还探讨了内部bean的概念及其与外部bean的比较,并提供了相应的示例代码和测试结果。
Spring5入门到实战------3、IOC容器-Bean管理XML方式(一)