Spring: Spring Framework(Spring 框架)Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的 应⽤程序开发起来更简单。用一句简单的话来说,Spring就是一个拥有众多工具的ioc容器。
容器: ⽤来容纳某种物品的(基本)装置
在我们学习Java基础的时候,就接触过一些关于数据结构的容器,他们都是根据一定的组织结构来组织众多的数据,例如:Map,List,Stack,Queue... 它们是组织数据的容器。
Spring也是一个容器。是一个IOC容器。
IOC(Inversion of control) 翻译为控制反转,IOC不是一种技术而是一种设计思想,其实这里的控制反转指的是,我们在创建对象的时候,对象的创建控制权交给了外部,在使用对象时,在程序中不要自己使用new创建对象,转换成为由外部主动提供对象。ioc容器用于充当ioc思想中的外部
IOC容器负责对象的创建,初始化等一系列的工作,被创建或者被管理的对象在IOC容器中统称为Bean
在传统程序设计,我们直接在对象内部通过new进行创建对象。如果我们在A类中需要一个B类中的对象,那按照以前我们在A类中就可以直接new出一个B类型的对象,那么此时我们不妨想一下,如果这个在A类中需要B类对象的时候,直接new 出B类型对象的思想,放到复杂的项目中,那么就有可能程序的调用链就会很长。例如:在A类中new一个B类型的对象,在B类中new一个C类型的对象,在C类中new一个D类型的对象… 那么如果此时的程序需求一旦有了变化,那么就会牵一发而动全身,这些类中的代码都需要改动。传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象
那么既然Spring是一个拥有众多工具的ioc容器,那么Spring这个容器就有控制反转的思想,那么是谁控制谁,又控制了什么,为什么在Spring中需要控制反转。
是谁控制谁?控制了什么?
其实
Spring的ioc容器,控制了在类中创建和管理对象的权限。也就是ioc容器控制了在该类中new出其他类型的对象。在传统的程序设计中,如果要想在A类中得到B类型的对象,那么就会直接new出B类型的对象,但是在这样的操作在后期维护代码的时候是非常费劲的。只要在A类中依赖的B对象的成员属性如果需要改动,那么整个代码就要进行大规模的更改。 但是如果使用的ioc容器,创建和管理对象的权限就交给了ioc容器。把B对象传给ioc容器,当我们在A类中需要B对象的时候,只要引用Spring ioc 容器中的B对象即可。
为什么Spring需要控制反转,在Spring中又控制反转了什么?
因为在传统的程序设计中,如果要想在A类中得到B类型的对象,那么就会直接new出B类型的对象,但是在这样的操作在后期维护代码的时候是非常费劲的。只要在A类中依赖的B对象的成员属性如果需要改动,那么整个代码就要进行大规模的更改。,在ioc容器中创建和管理对象,在容器中创建对象A,并且有该容器管理A对象。当在类A中需要对象B的时候,那么此时就不需要在类A中创建出一个对象B,此时对象A中的引用就可以被动的接受ioc容器中传来的对象B.
spring ioc 优点:
成功实现了解耦, 耦合是指:两个或两个以上对象存在依赖,当一方修改之后会影响另一方,那么就说这些对象间存在耦合。我们知道较好的代码应该是 "高内聚,低耦合 "的。这里把创建和管理对象的权限交给了ioc容器。
我们目前知道了Spring是一个拥有众多工具的IOC容器,那么怎样理解这就话呢?
所谓的容器:最大的用处就是把某物添加到容器中,再从容器中把某物取出来,这里的spring ioc容器也是一样的。IOC的核心:就是把bean添加到ioc容器中,然后在从ioc容器中把bean对象取出来。 其实Spring ioc 是一种具体的思想。它不是一种具体的行为措施。
将对象存放到容器中的好处:将对象存储在 IoC 容器相当于 将以后可能⽤的所有⼯具制作好都放到仓库中,需要的时候直接取就⾏了,⽤完再把它放回到仓库。 ⽽ new 对象的⽅式相当于,每次需要⼯具 了,才现做,⽤完就扔掉了也不会保存,下次再⽤的时候还得重新做,这就是 IoC 容器和普通程序开 发的区别。
DI (Dependency Injection) “依赖注⼊”
那么什么又是“依赖注入”?
在ioc容器中创建bean 和 bean之间依赖关系的整个过程 ,使用对象的时候不仅可以直接从ioc容器获取,并且获取到的bean已经绑定了所有的依赖关系。
所谓依赖注⼊,就是由 IoC 容器在运⾏期间,动态地将某种依赖关系注⼊到对象之中。所以, 赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC 容 器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦。
依赖注入不是一种设计实现,而是一种具体的技术,它是在 IoC 容器运行期间,动态地将某个依赖对象注入到当前对象的技术就叫做DI(依赖注入)。
IoC 和 DI 都是 Spring 框架中的重要概念,它们都是用来实现对象解耦的,其中 IoC(控制反转)是一种设计思想,而 DI(依赖注入)是一种具体的实现手段。
第一步:先创建一个maven 项目 

第二步:在spring_test项目中配置pom.xml文件,因为我们要基于maven创建一个Spring项目,所以要引入一个spring-context(Spring上下文)依赖,还有要把bean对象添加到spring中,就需要引入spring_beans依赖我们也可以在maven的官网去找。

这里就是spring-context和spring-beans依赖,可以直接添加到pom.xml文件中,加入之后在idea的右边栏maven栏中点击重新加载按钮。
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<ersion>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
</dependencies>
到此我们的第一个spring项目基本就创建完成了,但是我们还要往spring ioc容器中添加对象。
在 src --> main --> resource中添加配置,在resource下创建一个文件,这个文件名可以随便起,但是在这里还是简明知意的好,在这里我们创建一个spring-config.xml文件,并且在这个.xml文件中写入如下内容。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
</beans>
此时还没有引入bean对象到ioc 容器中。那么就要在这个spring-config.xml中写入一下信息,即就把bean对象添加到了spring ioc容器中了。
如果要想再spring ioc 容器中添加对象,
com.model包下先创建一个User类,在这个类中创建一个sayHi()方法
package com.model;
public class User {
public void sayHi(){
System.out.println("say hi");
}
}
那么就在 标签中添加对象即可,其中在标签中的属性有 id 其中 这个 id表示的是在从spring ioc 容器中得到相应对象的时候的beanName,就是通过这个beanName就可以找到spring ioc 容器中找到这个对象 还有一个属性 class 表示的是这个spring ioc 容器中的user对象所在的类,就是一个具体的类的路径
<beans>
<bean id = "user" class="com.model.User"></bean>
</beans>
创建一个App类,在该类中得到存入spring ioc 容器中的user对象,那么此时就不得不介绍一下spring的上下文对象了
spring上下文即是Spring容器抽象的一种实现;而我们常见的
ApplicationContext本质上说就是一个维护Bean定义以及对象之间协作关系的高级接口
一种是不常用的BeanFactory,这是最简单的容器,只能提供基本的DI功能;还有一种就是继承了BeanFactory后派生而来的应用上下文,其抽象接口也就是我们上面提到的的ApplicationContext,它能提供更多企业级的服务,例如解析配置文本信息等等,这也是应用上下文实例对象最常见的应用场景。有了上下文对象,我们就能向容器注册需要Spring管理的对象了。
ApplicationContext 和 BeanFactory 的区别:
相同点: 都可以实现从容器中获取Bean,都提供了getBean()方法。
不同点:
如果使用
BeanFactory作为spring的上下文对象,在加载spring-config配置文件的时候,是按需加载的,也就是说我现在在这个类中需要使用到spring ioc 容器所管理的某个对象,那么此时只把我要的Bean对象进行加载,这种就属于懒汉模式,你要的时候,我才给你拿。但是每次加载spring-config.xml文件中的某个对象到spring ioc容器会消耗一部分时间,相比,AppliactionContext作为spring的上下文对象,在spring ioc 容器加载时,就会把spring-config.xml文件中的全部Bean对象加载进来。如果在以后从spring ioc 容器中获取对象的时候,直接获取即可,无需加载,这样只是第一次加载spring-config.xml文件的时候,时间会消耗长一点。所以说在计算机中,懒汉模式不一定比饿汉模式好
在model包下,在创建出一个User2类,并且把这个user2对象,添加到 spring ioc 容器中。
package com.model;
public class User2 {
//在spring ioc 容器加载user2 对象到 spring ioc 容器的时候就会调用User2类中的构造方法
public User2(){
System.out.println("加载User2类");
}
public void sayHi(){
System.out.println("hello world");
}
}
//把user2对象添加到spring ioc 容器中
<bean id="user2" class="com.model.User2"></bean>
在User类中,添加一个无参的构造方法
package com.model;
public class User {
public User(){
System.out.println("加载User类");
}
public void sayHi(){
System.out.println("say hi");
}
}
在AppliactionContext作为spring上下文对象的时候,会一次性加载spring-config.xml中的所有Bean

在BeanFactory作为spring上下文对象的时候,会按需加载spring-config.xml中的Bean对象。

言回正传,从spring ioc 容器中获取对象。
public class App {
public static void main(String[] args) {
// 使用ApplicationContext作为spring的上下文对象,把spring-config.xml文件作为参数传给这个对象。就能通过getBean()方法,得到spring ioc 容器中所管理的对象。
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//因为getBean()方法的返回值是一个Object的类型,所以要在这里进行强制类型转换
User user = (User) context.getBean("user");
//得到spring ioc 中的对象,调用对象所在类的方法
user.sayHi();
}
}
在上述到代码中,一定要注意的是在getBean()方法中,所传入的参数一定要和spring-config.xml文件中Bean对象的id是一样的。
getBean()方法的更多用法:
UserController user = context.getBean(UserController.class); 根据类的类型,在spring ioc 容器中获得Bean对象UserController user = context.getBean("user", UserController.class); 根据类的类型,和在spring-config.xml文件中的Bean的id在spring ioc 容器中获得Bean对象UserController user = context.getBean("user") 根据spring-config.xml文件中的Bean的id在spring ioc 容器中获得Bean对象但是第一种方法获得Bean对象,有一个诟病,那就是如果在spring-config.xml配置文件中出现了两个相同的类型网spring ioc容器中添加Bean对象,那么在按照对象的类型在spring ioc 容器中获得对象的时候,就不知道你此时要获取那个对象(此时spring ioc 容器中有多个类型相同的对象)

运行结果:

期望有一个匹配的 bean,但是找到了2: user,user2 所以说在spring ioc 容器中如果存在相同类型的对象时,就不能使用上述的第一种方法从容器中获得对象。
那么此时的第二种getBean()的重载方法就应运而生,在getBean()方法中的参数为Bean的 id 和 这个Bean的类型。

运行结果:

第三种方法,我们已经在上述代码中介绍过了,在这里不做赘述。
概述以上流程:

其实这里所说的更简单的读取和存储对象,就是注解式编程,那么什么是注解式编程呢?
注解用来定义一个类。属性或一些方法,以便程序能被编译处理。它相当于一个说明文件,告诉应用程序某个被注解的类或属性是什么,要怎么处理,注解可以用于标志包,类,方法和变量等。
前置工作在spring-config.xml文件中配置一下内容:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<content:component-scan base-package="com.model"></content:component-scan>
</beans>
其中配置文件中的: 中的base-package表示要在该com.model包中扫描是否有5大类注解修饰的类,如果有那么就把这个类的对象添加到spring ioc 容器中。
那么什么又是5大类注解哪?
想要将对象存储在 Spring 中,有两种注解类型可以实现:
@Controller、@Service、@Repository、@Component、@Configuration。@Bean在model包下,新建一个UserController类
package com.model;
import org.springframework.stereotype.Controller;
//在spring-config.xml配置文件中的base-package就会扫表这个包中是否有那个类上到有上述的5大类注解,就会把对应的对象添加到spring ioc 容器中
//在这里就可以通过@Controller注解,把userController对象添加到spring ioc容器中
@Controller
public class UserController {
public void sayHi(){
System.out.println("hi controller");
}
}
那么此时怎样从spring ioc 容器中取出对象呢?
首先有一种方法,就是根据spring ioc 容器中的对象的类型在容器中寻找。使用UserController controller = context.getBean(UserController.class)从spring ioc 容器中得到对象。

那么如果spring ioc容器中有两个类型相同的对象,那么使用上述的这种方法就是不对的。
在这里我们还是把类名的第一个字母该文小写,试使用userController作为beanName 和 类型作为参数,是否能从spring ioc 容器中找到响应的对象。

那么为什么这种BeanName的写法是正确可用的,那如果就使用原本的类名(首字母大写),作为BeanName可不可以获得ioc 中的对象呢?

从运行结果中,我们可以看返回的错误提示:没有名为'UserController'可用 所以说不能使用类名来充当BeanName.
那么在idea中是如何定义BeanName的格式的呢?

public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&2
Character.isUpperCase(name.charAt(0))){
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
解读一下上述的代码: 起先这里的BeanName 起先是从类名变化来的
- 如果传来的BeanName 为 null 或者 BeanName 的字符串长度为0,那么就直接返回这个空字符串
- 如果类名的字符串程度大于1,并且类名的第一个字符和第二个字符都为大写,那么这个类名,就可以直接返回为BeanName
- 把类名的第一个字符转变成为小写,进行返回,返回之后的结果就是BeanName.

package com.model;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public void sayHi(){
System.out.println("hi Service");
}
}

package com.model;
import org.springframework.stereotype.Repository;
@Repository
public class UserRepository {
public void sayHi(){
System.out.println("hi Repository");
}
}

package com.model;
import org.springframework.stereotype.Component;
@Component
public class UserComponent {
public void sayHi(){
System.out.println("hi Component");
}
}

package com.model;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserConfiguration {
public void sayHi(){
System.out.println("hi UserConfiguration");
}
}

我们可以在上述得代码中看到,这五大类注解的功能都是一样的,都是把所修饰的类的对象添加到spring ioc 容器中,那么为什么要规定这么多的注解功能相同,只是名字不同的注解呢?
其实我们根据五大类注解的汉语意思也可以想到,@Controller 表示的是数据控制层,@Service 表示的是服务层,@Repository 数据持久层(操作数据库层),@Configuration 表示的是配置层。@Component 表示的是组件。 这样的分层是为以后管理代码,有了明确的规范,简单的说就是方便管理复杂程序中的代码,如果在一个复杂的项目中,所有的程序都写到一个类注解下,那么代码得有多长。

各个类注解之间的关系

我们可以在 @Controller @Service @ Configuration @ Respository 的源码中清晰的看到这四类注解分别都继承了@Component 注解
那么如果在一个类中的一个具体的方法中,这个方法的返回值是一个具体对象的时候,需要把这个方法返回的对象添加到spring ioc 容器中进行管理,那么该怎么呢?
使用@Bean 方法注解 但是光是用方法注解还是不行滴!,需要配合五大类注解中的一个,这样扫描类注解修饰的类的时候,才能扫描到这个@Bean注解所修饰的方法。
package com.model;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class UserBeans {
@Bean
public User retUser(){
User user = new User();
user.setUsername("张三");
user.setPassword("123456");
return user;
}
}
在User类中,声明了 username 用户名,password 用户密码 这个方法返回一个User对象。
从spring ioc 容器中获得User对象
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
User user = context.getBean("retUser",User.class);
System.out.println(user);
}
}
注意在这里 在没有重命名BeanName之前,如果要从spring ioc 容器中的到user对象。那么此时的BeanName默认就是,在UserBeans类下的返回User对象的 方法名。
重命名 Bean
在上述的代码中,如果要得到 ioc容器中的User对象,需要使用方法名作为BeanName,这样就不利于BeanName的规范,所以需要把BeanName重命名。
@Component
public class UserBeans {
@Bean(name = "user")
public User retUser(){
User user = new User();
user.setUsername("张三");
user.setPassword("123456");
return user;
}
}
@Bean 注解提供了一个 name属性,可以重命名BeanName.

但是此处需要谨记,这里如果把BeanName 重命名之后,那么就不能那原来的方法名作为BeanName了,否则就会报错。
前面介绍了更简单的方法把Bean从spring ioc 容器中存进去,那么是否有从ioc 容器中把Bean取出来还有简单的方法呢?
对象装配(对象注⼊)的实现⽅法以下 3 种:
把spring ioc 中的一个对象,添加到一个对象中,于是我们就能联系到上述所说的 DI(依赖注入)@Autowired,另一个注解是@Resource package com.model;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserConfiguration {
@Bean(name = "user")
public User retUser(){
User user = new User();
user.setUsername("lisi");
user.setPassword("123456");
return user;
}
}
使用@Autowired 属性注入
package com.model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class UserRepository {
@Autowired
private UserConfiguration configuration;
public User getUser(){
User user = configuration.retUser();
return user;
}
}
使用@Resource 属性注入
package com.model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class UserRepository {
@Resource
private UserConfiguration configuration;
public User getUser(){
User user = configuration.retUser();
return user;
}
}

这样就可以使用注解把spring ioc 容器中的对象取出来,在其他的类中调用这个对象原有类中的方法。
使用@Autowired 构造方法注入
package com.model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService){
this.userService = userService;
}
//在UserController类中就可以调用UserService类中的方法
public void say(){
userService.sayHi();
}
}
在这里还要说上一嘴,其实当在使用构造方法注入的时候,如果只是在这个类中只涉及到一个属性注入,就是说就在该类中创建一个依赖关系,那么此时就不用@Autowried注解。

使用@Autowired setter方法注入
package com.model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService){
this.userService = userService;
}
//在UserController类中就可以调用UserService类中的方法
public void say(){
userService.sayHi();
}
}
使用 @Resource setter方法注入
@Controller
public class UserController {
private UserService userService;
@Resource
public void setUserService(UserService userService){
this.userService = userService;
}
//在UserController类中就可以调用UserService类中的方法
public void say(){
userService.sayHi();
}
}
当出现以下多个 Bean,返回同⼀对象类型时程序会报错

没有符合条件的类型为“ com.model. User”的 bean 可用: 预期的单个匹配 bean,但找到了2: user1,user2
在这里还需要说明一点,如果使用的是属性注入,那么就要从ioc容器中找到对应的对象,那么此时@Autowried默认是根据类的类型,在spring ioc 容器中查找对象的。那么此时我们使用@Service 和@Bean注解 在UserService类中,往spring ioc 容器中添加了两个相同的类型的对象,类型都是User的,那么此时@AutoWried即使是找到对象了,但是他不是到要哪个Bean,所以就会报出上述的错误。
那么此时 就不得不介绍一下 @Qualifier,在这个注解中提供了一个value属性,此时我们就可以指定从ioc容器中取出我们想要Bean

那么如果此时我们使用的是@Resouse 也 进行的是属性注入,这个注解是默认按照BeanName在ioc容器中找到Bean的,还是上述的情形,那么该怎样才能从spring ioc 容器中取到相应的Bean呢?
其实在
@Resouse注解中提供了一个属性name="",通过这个属性就可以找到相应的Bean

我们所熟知的作用域也许是这样的:
作用域是 在运行时代码中的某些特定部分中变量,函数和对象的可访问性。换句话说,作用域决定了代码区块中变量和其他资源的可见性。
public class test {
public static void main(String[] args) {
{
int a = 10;
}
System.out.println(a);
}
}
上述的代码,是会出现编译时错误的,因为变量a 不是一个全局变量。
那么接下来就介绍一个Bean的作用域:是指 Bean 在 Spring 整个框架中的某种⾏为模式
请看一下代码:

运行结果:

此时打印出来的居然是两个一样的结果,这是为什么呢?
操作以上问题的原因是因为 Bean 默认情况下是单例状态(singleton)也就是所有⼈的使⽤的都是同 ⼀个对象,使⽤单例可以很⼤程度上提⾼性能,所以在 Spring 中 Bean 的作⽤域默认也是 singleton 单例模式。singleton 单例作⽤域,就表 示 Bean 在整个 Spring 中只有⼀份,它是全局共享的,那么当其他⼈修改了这个值之后,那么另⼀个 ⼈读取到的就是被修改的值
Spring 容器在初始化⼀个 Bean 的实例时,同时会指定该实例的作⽤域。Spring有 6 种作⽤域, 最后四种是基于 Spring MVC ⽣效的:
singleton
官⽅说明:(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.
描述:该作⽤域下的Bean在IoC容器中只存在⼀个实例:获取Bean(即通applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是同⼀ 个对象
场景:通常⽆状态的Bean使⽤该作⽤域。⽆状态表示Bean对象的属性状态不需要更新
备注:Spring默认选择该作⽤域
prototype
request
每次http请求会创建新的Bean实例,类似于prototypesession
application(了解)
websocket(了解)
singleton 是 Spring Core 的作⽤域;application 是 Spring Web 中的作⽤域;
singleton 作⽤于 IoC 的容器,⽽ application 作⽤于 Servlet 容器。
设置 Bean 的作用域有两种方式
@Scope 注解就可以声明 Bean 的作用域,它既可以修饰方法也可以修饰类第一种方法:

每次对该作⽤域下的Bean的请求都会创建新的实例 还可以使用@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
第二种方法:


Bean 执⾏流程(Spring 执⾏流程):启动 Spring 容器 -> 实例化 Bean(分配内存空间,从⽆到有) -> Bean 注册到 Spring 中(存操作) -> 将 Bean 装配到需要的类中(取操作)
所谓的⽣命周期指的是⼀个对象从诞⽣到销毁的整个⽣命过程,我们把这个过程就叫做⼀个对象的⽣命周期
Bean 的⽣命周期分为以下 5 ⼤部分: Bean ⽣命周期
BeanNameAware、BeanFactoryAware、 ApplicationContextAware 的接⼝⽅法; 执⾏ BeanPostProcessor 初始化前置⽅法; 执⾏ @Component
public class BeanLife implements BeanNameAware {
public void setBeanName(String s) {
System.out.println("执⾏了 setBeanName ⽅法:" + s);
}
@PostConstruct
public void postConstruct() {
System.out.println("执⾏ PostConstruct()" + "初始化方法");
}
public void init() {
System.out.println("执⾏ BeanLifeComponent init-method" + "初始化");
}
@PreDestroy
public void preDestroy() {
System.out.println("执⾏:preDestroy()" + "销毁");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<content:component-scan base-package="com.bit.component">
</content:component-scan>
<beans>
<bean id="beanLifeComponent"
class="com.model.BeanLife" init-method="init"></bean>
</beans>
</beans>
