掌握Bean配置和解析技巧,轻松打造高效优美的应用程序
在现代软件开发中,应用程序的复杂性越来越高,因此需要使用一些技术来管理和组织应用程序的组件。其中一种技术就是Bean配置和解析。
Bean配置和解析是一种用于管理和组织应用程序组件的技术。通过使用Bean配置文件,开发人员可以轻松地定义和组合各种组件,例如服务、数据源、视图和控制器等。然后,通过Bean解析器,应用程序可以自动将这些组件实例化并将它们注入到应用程序中。
掌握Bean配置和解析技巧可以帮助开发人员更轻松地管理和维护应用程序,提高代码复用性和可维护性,从而实现更高效优美的应用程序。
在本文中,我们将介绍Bean配置和解析的基本概念,以及如何使用它来打造高效优美的应用程序。
🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
Bean配置元数据
Spring容器使用Bean配置元数据来创建和管理Bean。以下列出了Spring中使用的不同类型的Bean配置元数据:
使用XML文件来配置Bean最常见。我们可以使用XML声明Bean定义和使用Bean的关系,后者是通过控制反转(Inversion of Control, IoC)实现的。
Java注释是一种用于描述Java类、方法、参数等的语言元素。Spring利用了Java注释来简化Bean的配置。@Component、@Service、@Controller和@Repository是四种最常见的注释,用于声明一些类为Bean。
Java配置类与XML配置文件类似,用于声明Bean的定义。但不同的是,Java配置类不使用XML,而是使用Java类以编程方式配置Bean。
Bean生命周期
在Spring容器中,Bean遵循生命周期顺序序列。以下是Bean的生命周期顺序序列:
- 实例化Bean
- Bean属性填充
- Bean的初始化方法调用
- Bean准备使用
- Bean可用
- Bean销毁前的清理
- Bean销毁
下面是关于Bean的生命周期的详细说明:
实例化Bean
Bean的实例化发生在容器创建过程中。当我们使用XML配置文件声明Bean时,容器会根据Bean定义名称或ID创建Bean实例。如果我们使用注释或Java配置类声明Bean,则容器将使用反射机制创建Bean实例。
代码示例:
// 定义一个Person类
public class Person {
private String name;
private int age;
// 省略getter和setter方法
// ...
}
实例化一个Bean对象
Person person = new Person();
person.setName("John");
person.setAge(30);
如果你使用Spring框架,你也可以使用XML或JavaConfig配置文件来定义和实例化Bean。下面是一个使用XML配置文件创建一个名为 “person” 的Bean的示例:
<bean id="person" class="com.example.Person">
<property name="name" value="John" />
<property name="age" value="30" />
</bean>
此外,在Spring 5.0及更高版本中,你还可以使用注解来定义和注入Bean,而不是使用XML或JavaConfig配置文件。例如:
// 定义一个Person类,并使用@Component注解标识它是一个Bean
@Component
public class Person {
private String name;
private int age;
// 省略getter和setter方法
// ...
}
在另一个类中,通过@Autowired注解将Person对象注入进来
@Component
public class MyClass {
@Autowired
private Person person;
// 省略其他代码
// ...
}
Bean属性填充
Bean属性填充发生在Bean的实例化之后,容器将Bean的属性注入到新的实例中。注意,属性注入是通过Java反射API实现的,它会设置非final字段上的值,以及JavaBean的setter方法。
在Spring框架中,可以使用XML、JavaConfig 或注解来配置 Bean 属性填充。以下是这些方法的代码示例:
使用XML进行属性填充的示例
<bean id="person" class="com.example.Person">
<property name="name" value="John" />
<property name="age" value="30" />
<property name="address">
<bean class="com.example.Address">
<property name="street" value="123 Main Street" />
<property name="city" value="New York" />
<property name="state" value="NY" />
<property name="zip" value="10001" />
</bean>
</property>
</bean>
使用JavaConfig进行属性填充的示例
@Configuration
public class AppConfig {
@Bean
public Person person() {
Person person = new Person();
person.setName("John");
person.setAge(30);
person.setAddress(address());
return person;
}
@Bean
public Address address() {
Address address = new Address();
address.setStreet("123 Main Street");
address.setCity("New York");
address.setState("NY");
address.setZip("10001");
return address;
}
}
使用注解进行属性填充的示例
@Component
public class Person {
private String name;
private int age;
@Autowired
private Address address;
// 省略getter和setter方法
// ...
}
@Component
public class Address {
private String street;
private String city;
private String state;
private String zip;
// 省略getter和setter方法
// ...
}
注解方式需要确保已经启用了组件扫描,以自动识别 @Component 注解的类。同时还需要启用自动装配,以使得 @Autowired 注解生效。这可以通过在配置文件中添加以下内容来完成:
<context:component-scan base-package="com.example" />
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
Bean的初始化方法调用
在属性注入之后,容器会调用Bean的初始化方法。我们可以通过两种方式来为Bean定义初始化方法:Java注释和XML文件中的init-method属性。
代码示例:
在Spring框架中,可以使用XML、JavaConfig或注解来配置Bean的初始化方法调用。以下是这几种方式的代码示例:
使用XML配置Bean的初始化方法调用的代码示例
<bean id="person" class="com.example.Person" init-method="init">
<property name="name" value="John" />
<property name="age" value="30" />
<property name="address" ref="address" />
</bean>
<bean id="address" class="com.example.Address">
<property name="street" value="123 Main Street" />
<property name="city" value="New York" />
<property name="state" value="NY" />
<property name="zip" value="10001" />
</bean>
使用JavaConfig配置Bean的初始化方法调用的代码示例
@Configuration
public class AppConfig {
@Bean(initMethod = "init")
public Person person() {
Person person = new Person();
person.setName("John");
person.setAge(30);
person.setAddress(address());
return person;
}
@Bean
public Address address() {
Address address = new Address();
address.setStreet("123 Main Street");
address.setCity("New York");
address.setState("NY");
address.setZip("10001");
return address;
}
}
使用注解配置Bean的初始化方法调用的代码示例
@Component
public class Person {
private String name;
private int age;
@Autowired
private Address address;
@PostConstruct
public void init() {
// 执行初始化逻辑
}
// 省略getter和setter方法
// ...
}
@Component
public class Address {
private String street;
private String city;
private String state;
private String zip;
// 省略getter和setter方法
// ...
}
无论使用哪种方式,都需要在Bean类中定义初始化方法,然后使用init-method属性(XML方式)或initMethod属性(JavaConfig方式)或@PostConstruct注解(注解方式)将该方法与Bean关联起来。注意,初始化方法的访问修饰符必须是public,返回类型必须是void,且方法名可以是任意的。初始化方法在Bean实例化之后被调用,用于进行一些必要的初始化工作。
Bean准备使用
在Bean初始化方法调用之后,Bean被标记为准备使用。此时Bean可以被调用或者被其他Bean引用。
代码示例:
在Spring框架中,可以使用XML、JavaConfig或注解来配置Bean的预处理方法调用。以下是这几种方式的代码示例:
使用XML配置Bean预处理方法调用的代码示例
<bean id="person" class="com.example.Person" lazy-init="true" init-method="init" destroy-method="destroy">
<property name="name" value="John" />
<property name="age" value="30" />
<property name="address" ref="address" />
</bean>
<bean id="address" class="com.example.Address" lazy-init="true">
<property name="street" value="123 Main Street" />
<property name="city" value="New York" />
<property name="state" value="NY" />
<property name="zip" value="10001" />
</bean>
上述示例配置属性 lazy-init=“true”,表示延迟初始化 Bean,即在第一次使用 Bean 时再进行实例化和属性注入。另外,示例配置了 init-method 和 destroy-method 属性,用于指定 Bean 实例的初始化方法和销毁方法。
使用JavaConfig配置Bean预处理方法调用的代码示例
@Configuration
public class AppConfig {
@Bean(initMethod = "init", destroyMethod = "destroy")
@Lazy
public Person person() {
Person person = new Person();
person.setName("John");
person.setAge(30);
person.setAddress(address());
return person;
}
@Bean
@Lazy
public Address address() {
Address address = new Address();
address.setStreet("123 Main Street");
address.setCity("New York");
address.setState("NY");
address.setZip("10001");
return address;
}
}
上述示例在 @Bean 注解上使用了 @Lazy 注解,表示延迟初始化 Bean,在第一次使用 Bean 时再进行实例化和属性注入。同时,示例使用 initMethod 和 destroyMethod 属性指定 Bean 实例的初始化方法和销毁方法。
使用注解配置Bean预处理方法调用的代码示例
@Component
@Lazy
@Scope("prototype")
public class Person {
private String name;
private int age;
@Autowired
private Address address;
@PostConstruct
public void init() {
// 执行初始化逻辑
}
@PreDestroy
public void destroy() {
// 执行清理逻辑
}
// 省略getter和setter方法
// ...
}
@Component
@Lazy
public class Address {
private String street;
private String city;
private String state;
private String zip;
// 省略getter和setter方法
// ...
}
上述示例在 @Lazy 注解上指定了延迟初始化 Bean,在第一次使用 Bean 时再进行实例化和属性注入。同时,示例定义了一个 @PreDestroy 注解的方法,用于实现 Bean 实例的销毁逻辑。注意,对于prototype作用域的Bean,Spring不会自动销毁。
Bean可用
当Bean被完全初始化后,它被标记为可用。在这个阶段,它可以被其他Bean引用和使用。
代码示例:
简单的 Java 代码示例,用于演示Bean被标记为可用后,可以被其他Bean引用和使用:
@Component
public class Address {
private String street;
private String city;
private String state;
private String zip;
// 省略getter和setter方法
// ...
public String toString() {
return street + ", " + city + ", " + state + " " + zip;
}
}
@Component
public class Person {
private String name;
private int age;
@Autowired
private Address address;
public void sayHello() {
System.out.println("Hello, my name is " + name + " and I live at " + address);
}
// 省略getter和setter方法
// ...
}
@Configuration
public class AppConfig {
@Bean
public Address address() {
Address address = new Address();
address.setStreet("123 Main Street");
address.setCity("New York");
address.setState("NY");
address.setZip("10001");
return address;
}
@Bean
public Person person() {
Person person = new Person();
person.setName("John");
person.setAge(30);
person.setAddress(address()); // 引用Address Bean
return person;
}
}
// 在另一个Java类中
public class Test {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Person person = context.getBean(Person.class);
person.sayHello(); // 引用了Address Bean
}
}
在上述示例中,通过在 Person 类中使用 @Autowired 注解,引用了 Address Bean。同时,通过在 AppConfig
类的 person() 方法中调用 address() 方法,将 Address Bean 注入到 Person Bean 中。最后,在
Test 类的 main 方法中,通过 ApplicationContext 获取 Person Bean 实例,并调用它的
sayHello() 方法,输出介绍自己和自己的住址的信息。
Bean销毁前的清理
在Bean准备销毁之前,Spring容器将调用Bean销毁之前的清理方法。我们可以通过Java注释和XML文件中的destroy-method属性来定义这个清理方法。
代码示例:
在Spring框架中,我们可以通过Java注释和XML文件中的destroy-method属性来定义Bean销毁之前的清理方法。以下是代码示例,使用这两种方法来实现Bean销毁之前的清理:
使用Java注释定义Bean销毁之前的清理方法
@Component
public class MyBean {
// 在Bean销毁之前执行的清理方法
@PreDestroy
public void cleanup() {
// 执行清理逻辑
}
// 该Bean的其他方法和属性
// ...
}
上述示例中,@PreDestroy 注释表示这个方法应该在Bean销毁之前被调用做清理。在这个方法中,可以加入一些清理 Bean 所占用的资源的代码。
使用XML文件定义Bean销毁之前的清理方法
<bean id="myBean" class="com.example.MyBean" destroy-method="cleanup">
<!-- 该Bean的其他属性 -->
</bean>
上述示例中,我们在XML文件中使用 destroy-method 属性来指定一个 Bean 销毁之前调用的方法的名称。例如,这里的 cleanup() 方法被定义为使用 destroy-method 属性调用的清理方法。
需要注意的是,使用 destroy-method 属性定义的清理方法必须不存在任何参数,且必须是 public
访问级别的。当然,Spring也会自动释放 Bean 内部使用的资源。例如,如果 Bean 定义了一个名为close()
的方法,并且实现了特定接口的实例,那么 Spring 将在销毁该 Bean 之前自动调用 close() 方法清理资源。
Bean销毁
最后,容器销毁Bean实例。这将触发Bean销毁之前的清理方法调用。
代码示例:
Bean销毁之前的清理方法的示例代码:
@Configuration
public class AppConfig {
@Bean(initMethod = "init", destroyMethod = "cleanup")
public MyBean myBean() {
return new MyBean();
}
}
public class MyBean {
/**
* 在Bean销毁之前执行的清理方法
*/
public void cleanup() {
// 执行清理逻辑
}
// 该Bean的其他方法和属性
// ...
}
在上述示例中,我们在 @Bean 注解中使用 destroyMethod 属性指定 bean 实例销毁前调用的清理方法名称。在 MyBean 类中实现 cleanup() 方法,将会在 bean 实例销毁前被调用执行。
需要注意的是,无论是通过 Java 配置还是 XML 配置,Bean 的销毁方法需要是 public 访问级别的且不带参数的。如果 Bean 实例实现了 DisposableBean 接口,那么也可以利用该接口的 destroy
总结
在本文中,我们讨论了Bean配置和解析的不同方法,以及Bean的生命周期序列。我们发现,在Spring中,Bean是非常重要的概念。了解Bean的配置和生命周期是开发Spring应用程序的基本要求。
相关文章
- Redis安装与配置
- Java 开发环境配置--eclipse工具进行java开发
- 《转》IIS中配置通配符应用程序映射
- Nagios学习实践系列——配置研究[监控当前服务器]
- .Net 自定义应用程序配置
- 在 Tomcat 中配置 SSL/TLS 以支持 HTTPS
- apache+jetty 配置web jsp服务器负载均衡
- gradle与android studio 关系及gradle配置
- yarn配置日志聚合:将日志都聚集到某一台服务器
- git 配置,代码提交到仓库,不小心将node_modules上传,处理操作。.gitignore 删除已提交的文件
- System.Web.HttpException (0x80004005): 验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。
- 华为防火墙基本配置
- tomcat8.0 基本参数调优配置
- ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存
- 华为运营商级路由器配置示例 | 跨域L3VdPdNdv4 over SRv6 TE Policy
- Win11应用程序启动提示配置不正确解决方法
- 我的sysmon采集全量数据配置
- vsftpd日志配置及查看——可以将vsftpd记录在系统日志里
- Docker重学系列之高级数据卷配置
- 【环境配置】Windows 11 的 WSL(Ubuntu2204) 安装OpenCV 4.5.4 (亲测有效)
- zabbix主动模式与被动模式区别以及详细配置(二十一)
- honeywell 6100ep配置网络连接