1.Spring IoC容器和核心概念
1.1 组件和组件管理概念
-
1.1.1 什么是组件?
回顾常规的三层架构处理请求流程:
-
1.1.2 我们的期待
-
有人替我们创建组件的对象
-
有人帮我们保存组件的对象
-
有人帮助我们自动组装
-
有人替我们管理事务
-
有人协助我们整合其他框架
-
......
-
-
1.1.3 Spring充当组件管理角色(IoC)
那么谁帮我们完成我们的期待,帮我们管理组件呢?
当然是Spring 框架了!
组件可以完全交给Spring 框架进行管理,Spring框架替代了程序员原有的new对象和对象属性赋值动作等!
Spring具体的组件管理动作包含:
-
组件对象实例化
-
组件属性属性赋值
-
组件对象之间引用
-
组件对象存活周期管理
-
...... 我们只需要编写元数据(配置文件)告知Spring 管理哪些类组件和他们的关系即可! 注意:组件是映射到应用程序中所有可重用组件的Java对象,应该是可复用的功能对象!
-
组件一定是对象
-
对象不一定是组件 综上所述,Spring 充当一个组件容器,创建、管理、存储组件,减少了我们的编码压力,让我们更加专注进行业务编写!
-
-
1.1.4 组件交给Spring管理优势!
-
降低了组件之间的耦合性:Spring IoC容器通过依赖注入机制,将组件之间的依赖关系削弱,减少了程序组件之间的耦合性,使得组件更加松散地耦合。
-
提高了代码的可重用性和可维护性:将组件的实例化过程、依赖关系的管理等功能交给Spring IoC容器处理,使得组件代码更加模块化、可重用、更易于维护。
-
方便了配置和管理:Spring IoC容器通过XML文件或者注解,轻松的对组件进行配置和管理,使得组件的切换、替换等操作更加的方便和快捷。
-
交给Spring管理的对象(组件),方可享受Spring框架的其他功能(AOP,声明事务管理)等
-
1.2 Spring IoC容器和容器实现
-
1.2.1 普通和复杂容器
普通容器只能用来存储,没有更多功能。 程序中的普通容器:
-
数组
-
集合:List
-
集合:Set
程序中的复杂容器:
Servlet 容器能够管理 Servlet(init,service,destroy)、Filter、Listener 这样的组件的一生,所以它是一个复杂容器。
名称 | 时机 | 次数 |
---|---|---|
创建对象 | 默认情况:接收到第一次请求 修改启动顺序后:Web应用启动过程中 | 一次 |
初始化操作 | 创建对象之后 | 一次 |
处理请求 | 接收到请求 | 多次 |
销毁操作 | Web应用卸载之前 | 一次 |
我们即将要学习的 SpringIoC 容器也是一个复杂容器。它们不仅要负责创建组件的对象、存储组件的对象,还要负责调用组件的方法让它们工作,最终在特定情况下销毁组件。 | ||
总结:Spring管理组件的容器,就是一个复杂容器,不仅存储组件,也可以管理组件之间依赖关系,并且创建和销毁组件等! |
1.2.2 SpringIoC容器介绍
Spring IoC 容器,负责实例化、配置和组装 bean(组件)。容器通过读取配置元数据来获取有关要实例化、配置和组装组件的指令。配置元数据以 XML、Java 注解或 Java 代码形式表现。它允许表达组成应用程序的组件以及这些组件之间丰富的相互依赖关系。
上图显示了 Spring 容器工作原理的高级视图。应用程序类与配置元数据相结合,您拥有完全配置且可执行的系统或应用程序。
1.2.3 SpringIoC容器具体接口和实现类
SpringIoc容器接口:
BeanFactory
接口提供了一种高级配置机制,能够管理任何类型的对象,它是SpringIoC容器标准化超接口!
ApplicationContext
是 BeanFactory
的子接口。它扩展了以下功能:
-
更容易与 Spring 的 AOP 功能集成
-
消息资源处理(用于国际化)
-
特定于应用程序给予此接口实现,例如Web 应用程序的
WebApplicationContext
简而言之,BeanFactory
提供了配置框架和基本功能,而ApplicationContext
添加了更多特定于企业的功能。ApplicationContext
是BeanFactory
的完整超集! ApplicationContext容器实现类:
类型名 | 简介 |
---|---|
ClassPathXmlApplicationContext | 通过读取类路径下的 XML 格式的配置文件创建 IOC 容器对象 |
FileSystemXmlApplicationContext | 通过文件系统路径读取 XML 格式的配置文件创建 IOC 容器对象 |
AnnotationConfigApplicationContext | 通过读取Java配置类创建 IOC 容器对象 |
WebApplicationContext | 专门为 Web 应用准备,基于 Web 环境创建 IOC 容器对象,并将对象引入存入 ServletContext 域中。 |
1.2.4 SpringIoC容器管理配置方式
Spring IoC 容器使用多种形式的配置元数据。此配置元数据表示您作为应用程序开发人员如何告诉 Spring 容器实例化、配置和组装应用程序中的对象。
Spring框架提供了多种配置方式:XML配置方式、注解方式和Java配置类方式
-
XML配置方式:是Spring框架最早的配置方式之一,通过在XML文件中定义Bean及其依赖关系、Bean的作用域等信息,让Spring IoC容器来管理Bean之间的依赖关系。该方式从Spring框架的第一版开始提供支持。
-
注解方式:从Spring 2.5版本开始提供支持,可以通过在Bean类上使用注解来代替XML配置文件中的配置信息。通过在Bean类上加上相应的注解(如@Component, @Service, @Autowired等),将Bean注册到Spring IoC容器中,这样Spring IoC容器就可以管理这些Bean之间的依赖关系。
-
Java配置类方式:从Spring 3.0版本开始提供支持,通过Java类来定义Bean、Bean之间的依赖关系和配置信息,从而代替XML配置文件的方式。Java配置类是一种使用Java编写配置信息的方式,通过@Configuration、@Bean等注解来实现Bean和依赖关系的配置。 为了迎合当下开发环境,我们将以配置类+注解方式为主进行讲解!
1.3 Spring IoC / DI概念总结
-
IoC容器
Spring IoC 容器,负责实例化、配置和组装 bean(组件)核心容器。容器通过读取配置元数据来获取有关要实例化、配置和组装组件的指令。
-
IoC(Inversion of Control)控制反转
IoC 主要是针对对象的创建和调用控制而言的,也就是说,当应用程序需要使用一个对象时,不再是应用程序直接创建该对象,而是由 IoC 容器来创建和管理,即控制权由应用程序转移到 IoC 容器中,也就是“反转”了控制权。这种方式基本上是通过依赖查找的方式来实现的,即 IoC 容器维护着构成应用程序的对象,并负责创建这些对象。
-
DI (Dependency Injection) 依赖注入
DI 是指在组件之间传递依赖关系的过程中,将依赖关系在容器内部进行处理,这样就不必在应用程序代码中硬编码对象之间的依赖关系,实现了对象之间的解耦合。在 Spring 中,DI 是通过 XML 配置文件或注解的方式实现的。它提供了三种形式的依赖注入:构造函数注入、Setter 方法注入和接口注入。
2.Spring IoC实践和应用
2.1 Spring IoC / DI 实现步骤
我们总结下,组件交给Spring IoC容器管理,并且获取和使用的基本步骤!
2.1.1配置元数据(配置)
配置元数据,既是编写交给SpringIoC容器管理组件的信息,配置方式有三种。
基于 XML 的配置元数据的基本结构:<bean id="..." [1] class="..." [2]> <!-- collaborators and configuration for this bean go here --> </bean>
<?xml version="1.0" encoding="UTF-8"?>
<!-- 此处要添加一些约束,配置文件的标签并不是随意命名 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." [1] class="..." [2]>
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
Spring IoC 容器管理一个或多个组件。这些 组件是使用你提供给容器的配置元数据(例如,以 XML <bean/>
定义的形式)创建的。
<bean /> 标签 == 组件信息声明
-
id
属性是标识单个 Bean 定义的字符串。 -
class
属性定义 Bean 的类型并使用完全限定的类名。
2.1.2实例化IoC容器
提供给 ApplicationContext
构造函数的位置路径是资源字符串地址,允许容器从各种外部资源(如本地文件系统、Java CLASSPATH
等)加载配置元数据。
我们应该选择一个合适的容器实现类,进行IoC容器的实例化工作:
//实例化ioc容器,读取外部配置文件,最终会在容器内进行ioc和di动作
ApplicationContext context =
new ClassPathXmlApplicationContext("services.xml", "daos.xml");
2.1.3获取Bean(组件)
ApplicationContext
是一个高级工厂的接口,能够维护不同 bean 及其依赖项的注册表。通过使用方法 T getBean(String name, Class<T> requiredType)
,您可以检索 bean 的实例。
允许读取 Bean 定义并访问它们,如以下示例所示:
//创建ioc容器对象,指定配置文件,ioc也开始实例组件对象
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
//获取ioc容器的组件对象
PetStoreService service = context.getBean("petStore", PetStoreService.class);
//使用组件对象
List<String> userList = service.getUsernameList();
2.2 基于XML配置方式组件管理
2.2.1 实验一: 组件(Bean)信息声明配置(IoC)
-
目标:Spring IoC 容器管理一个或多个 bean。这些 Bean 是使用您提供给容器的配置元数据创建的(例如,以 XML
<bean/>
定义的形式)。我们学习,如何通过定义XML配置文件,声明组件类信息,交给 Spring 的 IoC 容器进行组件管理! -
准备项目,创建maven工程(spring-ioc-xml-01),导入SpringIoC相关依赖
-
基于无参数构造函数
-
基于静态工厂方法实例化
-
基于实例工厂方法实例化
图解IoC配置流程:
2.2.2 实验二: 组件(Bean)依赖注入配置(DI)
-
目标
通过配置文件,实现IoC容器中Bean之间的引用(依赖注入DI配置)。
主要涉及注入场景:基于构造函数的依赖注入和基于 Setter 的依赖注入。
-
思路
3.基于构造函数的依赖注入(单个构造参数)
4.基于构造函数的依赖注入(多构造参数解析)
5.基于Setter方法依赖注入
总结:
依赖注入(DI)包含引用类型和基本数据类型,同时注入的方式也有多种!主流的注入方式为setter方法注入和构造函数注入,两种注入语法都需要掌握!
需要特别注意:引用其他bean,使用ref属性。直接注入基本类型值,使用value属性。
2.2.3 实验三: IoC容器创建和使用
-
介绍
上面的实验只是讲解了如何在XML格式的配置文件编写IoC和DI配置!
如图:
-
容器实例化
-
//方式1:实例化并且指定配置文件 //参数:String...locations 传入一个或者多个配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml"); //方式2:先实例化,再指定配置文件,最后刷新容器触发Bean实例化动作 [springmvc源码和contextLoadListener源码方式] ApplicationContext context = new ClassPathXmlApplicationContext(); //设置配置配置文件,方法参数为可变参数,可以设置一个或者多个配置 iocContainer1.setConfigLocations("services.xml", "daos.xml"); //后配置的文件,需要调用refresh方法,触发刷新配置 iocContainer1.refresh();
-
Bean对象读取
//方式1: 根据id获取
//没有指定类型,返回为Object,需要类型转化!
HappyComponent happyComponent =
(HappyComponent) iocContainer.getBean("bean的id标识");
//使用组件对象
happyComponent.doWork();
//方式2: 根据类型获取
//根据类型获取,但是要求,同类型(当前类,或者之类,或者接口的实现类)只能有一个对象交给IoC容器管理
//配置两个或者以上出现: org.springframework.beans.factory.NoUniqueBeanDefinitionException 问题
HappyComponent happyComponent = iocContainer.getBean(HappyComponent.class);
happyComponent.doWork();
//方式3: 根据id和类型获取
HappyComponent happyComponent = iocContainer.getBean("bean的id标识", HappyComponent.class);
happyComponent.doWork();
根据类型来获取bean时,在满足bean唯一性的前提下,其实只是看:『对象 instanceof 指定的类型』的返回结果,
只要返回的是true就可以认定为和类型匹配,能够获取到。
2.2.5 实验四: 高级特性:FactoryBean特性和使用
-
FactoryBean简介
FactoryBean
接口是Spring IoC容器实例化逻辑的可插拔性点。用于配置复杂的Bean对象,可以将创建过程存储在
FactoryBean
的getObject方法!FactoryBean<T>
接口提供三种方法:-
T getObject()
:返回此工厂创建的对象的实例。该返回值会被存储到IoC容器!
-
boolean isSingleton()
:如果此
FactoryBean
返回单例,则返回true
,否则返回false
。此方法的默认实现返回true
(注意,lombok插件使用,可能影响效果)。 -
Class<?> getObjectType()
: 返回getObject()
方法返回的对象类型,如果事先不知道类型,则返回null
。
-
-
FactoryBean使用场景
-
代理类的创建
-
第三方框架整合
-
复杂对象实例化等
-
-
Factorybean应用
-
准备FactoryBean实现类
-
// 实现FactoryBean接口时需要指定泛型
// 泛型类型就是当前工厂要生产的对象的类型
public class HappyFactoryBean implements FactoryBean<HappyMachine> {
private String machineName;
public String getMachineName() {
return machineName;
}
public void setMachineName(String machineName) {
this.machineName = machineName;
}
@Override
public HappyMachine getObject() throws Exception {
// 方法内部模拟创建、设置一个对象的复杂过程
HappyMachine happyMachine = new HappyMachine();
happyMachine.setMachineName(this.machineName);
return happyMachine;
}
@Override
public Class<?> getObjectType() {
// 返回要生产的对象的类型
return HappyMachine.class;
}
}
2.配置FactoryBean实现类
<!-- FactoryBean机制 -->
<!-- 这个bean标签中class属性指定的是HappyFactoryBean,但是将来从这里获取的bean是HappyMachine对象 -->
<bean id="happyMachine7" class="com.atguigu.ioc.HappyFactoryBean">
<!-- property标签仍然可以用来通过setXxx()方法给属性赋值 -->
<property name="machineName" value="iceCreamMachine"/>
</bean>
3.测试读取FactoryBean和FactoryBean.getObject对象
@Test
public void testExperiment07() {
ApplicationContext iocContainer = new ClassPathXmlApplicationContext("spring-bean-07.xml");
//注意: 直接根据声明FactoryBean的id,获取的是getObject方法返回的对象
HappyMachine happyMachine = iocContainer.getBean("happyMachine7",HappyMachine.class);
System.out.println("happyMachine = " + happyMachine);
//如果想要获取FactoryBean对象, 直接在id前添加&符号即可! &happyMachine7 这是一种固定的约束
Object bean = iocContainer.getBean("&happyMachine7");
System.out.println("bean = " + bean);
}
4.FactoryBean和BeanFactory区别
**FactoryBean **是 Spring 中一种特殊的 bean,可以在 getObject() 工厂方法自定义的逻辑创建Bean!是一种能够生产其他 Bean 的 Bean。FactoryBean 在容器启动时被创建,而在实际使用时则是通过调用 getObject() 方法来得到其所生产的 Bean。因此,FactoryBean 可以自定义任何所需的初始化逻辑,生产出一些定制化的 bean。
一般情况下,整合第三方框架,都是通过定义FactoryBean实现!!!
BeanFactory 是 Spring 框架的基础,其作为一个顶级接口定义了容器的基本行为,例如管理 bean 的生命周期、配置文件的加载和解析、bean 的装配和依赖注入等。BeanFactory 接口提供了访问 bean 的方式,例如 getBean() 方法获取指定的 bean 实例。它可以从不同的来源(例如 Mysql 数据库、XML 文件、Java 配置类等)获取 bean 定义,并将其转换为 bean 实例。同时,BeanFactory 还包含很多子类(例如,ApplicationContext 接口)提供了额外的强大功能。
总的来说,FactoryBean 和 BeanFactory 的区别主要在于前者是用于创建 bean 的接口,它提供了更加灵活的初始化定制功能,而后者是用于管理 bean 的框架基础接口,提供了基本的容器功能和 bean 生命周期管理。
2.3 基于 注解 方式管理 Bean
2.3.1 实验一: Bean注解标记和扫描 (IoC)
-
注解理解
和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作。
本质上:所有一切的操作都是 Java 代码来完成的,XML 和注解只是告诉框架中的 Java 代码如何执行。
举例:元旦联欢会要布置教室,蓝色的地方贴上元旦快乐四个字,红色的地方贴上拉花,黄色的地方贴上气球。班长做了所有标记,同学们来完成具体工作。标记相当于我们在代码中使用的注解,后面同学们做的工作,相当于框架的具体操作。
-
扫描理解
Spring 为了知道程序员在哪些地方标记了什么注解,就需要通过扫描的方式,来进行检测。然后根据注解进行后续操作。
-
准备Spring项目和组件
-
准备项目pom.xml
-
<dependencies> <!--spring context依赖--> <!--当你引入Spring Context依赖之后,表示将Spring的基础依赖引入了--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.0.6</version> </dependency> <!--junit5测试--> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.3.1</version> </dependency> </dependencies>
-
3.准备组件类
普通组件
/**
* projectName: com.atguigu.components
*
* description: 普通的组件
*/
public class CommonComponent {
}
Controller组件
/**
* projectName: com.atguigu.components
*
* description: controller类型组件
*/
public class XxxController {
}
Service组件
/**
* projectName: com.atguigu.components
*
* description: service类型组件
*/
public class XxxService {
}
Dao组件
/**
* projectName: com.atguigu.components
*
* description: dao类型组件
*/
public class XxxDao {
}
4.组件添加标记注解
Spring 提供了以下多个注解,这些注解可以直接标注在 Java 类上,将它们定义成 Spring Bean。
注解 | 说明 |
---|---|
@Component | 该注解用于描述 Spring 中的 Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(Bean),并且可以作用在应用的任何层次,例如 Service 层、Dao 层等。 使用时只需将该注解标注在相应类上即可。 |
@Repository | 该注解用于将数据访问层(Dao 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。 |
@Service | 该注解通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。 |
@Controller | 该注解通常作用在控制层(如SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。 |
5.配置文件确定扫描范围
<?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:context="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">
<!-- 配置自动扫描的包 -->
<!-- 1.包要精准,提高性能!
2.会扫描指定的包和子包内容
3.多个包可以使用,分割 例如: com.atguigu.controller,com.atguigu.service等
-->
<context:component-scan base-package="com.atguigu.components"/>
</beans>
总结:
- 注解方式IoC只是标记哪些类要被Spring管理
-
最终,我们还需要XML方式或者后面讲解Java配置类方式指定注解生效的包
-
现阶段配置方式为 注解 (标记)+ XML(扫描)
2.4 基于 配置类 方式管理 Bean
2.4.1 完全注解开发理解
Spring 完全注解配置(Fully Annotation-based Configuration)是指通过 Java配置类 代码来配置 Spring 应用程序,使用注解来替代原本在 XML 配置文件中的配置。相对于 XML 配置,完全注解配置具有更强的类型安全性和更好的可读性。
两种方式思维转化:
2.4.2 实验一:配置类和扫描注解
**xml+注解方式**
配置文件application.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:context="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">
<!-- 配置自动扫描的包 -->
<!-- 1.包要精准,提高性能!
2.会扫描指定的包和子包内容
3.多个包可以使用,分割 例如: com.atguigu.controller,com.atguigu.service等
-->
<context:component-scan base-package="com.atguigu.components"/>
<!-- 引入外部配置文件-->
<context:property-placeholder location="application.properties" />
</beans>
测试创建IoC容器
// xml方式配置文件使用ClassPathXmlApplicationContext容器读取
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("application.xml");
配置类+注解方式(完全注解方式)
配置类
使用 @Configuration 注解将一个普通的类标记为 Spring 的配置类。
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
//标注当前类是配置类,替代application.xml
@Configuration
//使用注解读取外部配置,替代 <context:property-placeholder标签
@PropertySource("classpath:application.properties")
//使用@ComponentScan注解,可以配置扫描包,替代<context:component-scan标签
@ComponentScan(basePackages = {"com.atguigu.components"})
public class MyConfiguration {
}
测试创建IoC容器
// AnnotationConfigApplicationContext 根据配置类创建 IOC 容器对象
ApplicationContext iocContainerAnnotation =
new AnnotationConfigApplicationContext(MyConfiguration.class);
可以使用 no-arg 构造函数实例化 AnnotationConfigApplicationContext
,然后使用 register()
方法对其进行配置。此方法在以编程方式生成 AnnotationConfigApplicationContext
时特别有用。以下示例演示如何执行此操作:
// AnnotationConfigApplicationContext-IOC容器对象
ApplicationContext iocContainerAnnotation =
new AnnotationConfigApplicationContext();
//外部设置配置类
iocContainerAnnotation.register(MyConfiguration.class);
//刷新后方可生效!!
iocContainerAnnotation.refresh();
总结:
@Configuration指定一个类为配置类,可以添加配置注解,替代配置xml文件
@ComponentScan(basePackages = {"包","包"}) 替代<context:component-scan标签实现注解扫描
@PropertySource("classpath:配置文件地址") 替代 <context:property-placeholder标签
配合IoC/DI注解,可以进行完整注解开发!
2.4.3 实验二:@Bean定义组件
场景需求:将Druid连接池对象存储到IoC容器
需求分析:第三方jar包的类,添加到ioc容器,无法使用@Component等相关注解!因为源码jar包内容为只读模式!
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:context="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">
<!-- 引入外部属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 实验六 [重要]给bean的属性赋值:引入外部属性文件 -->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
配置类方式实现:
@Bean
注释用于指示方法实例化、配置和初始化要由 Spring IoC 容器管理的新对象。对于那些熟悉 Spring 的 <beans/>
XML 配置的人来说, @Bean
注释与 <bean/>
元素起着相同的作用。
//标注当前类是配置类,替代application.xml
@Configuration
//引入jdbc.properties文件
@PropertySource({"classpath:application.properties","classpath:jdbc.properties"})
@ComponentScan(basePackages = {"com.atguigu.components"})
public class MyConfiguration {
//如果第三方类进行IoC管理,无法直接使用@Component相关注解
//解决方案: xml方式可以使用<bean标签
//解决方案: 配置类方式,可以使用方法返回值+@Bean注解
@Bean
public DataSource createDataSource(@Value("${jdbc.user}") String username,
@Value("${jdbc.password}")String password,
@Value("${jdbc.url}")String url,
@Value("${jdbc.driver}")String driverClassName){
//使用Java代码实例化
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);
//返回结果即可
return dataSource;
}
}
2.5 三种配置方式总结
2.5.1 XML方式配置总结
-
所有内容写到xml格式配置文件中
-
声明bean通过<bean标签
-
<bean标签包含基本信息(id,class)和属性信息 <property name value / ref
-
引入外部的properties文件可以通过<context:property-placeholder
-
IoC具体容器实现选择ClassPathXmlApplicationContext对象
2.5.2 XML+注解方式配置总结
-
注解负责标记IoC的类和进行属性装配
-
xml文件依然需要,需要通过<context:component-scan标签指定注解范围
-
标记IoC注解:@Component,@Service,@Controller,@Repository
-
标记DI注解:@Autowired @Qualifier @Resource @Value
-
IoC具体容器实现选择ClassPathXmlApplicationContext对象
2.5.3 完全注解方式配置总结
-
完全注解方式指的是去掉xml文件,使用配置类 + 注解实现
-
xml文件替换成使用@Configuration注解标记的类
-
标记IoC注解:@Component,@Service,@Controller,@Repository
-
标记DI注解:@Autowired @Qualifier @Resource @Value
-
<context:component-scan标签指定注解范围使用@ComponentScan(basePackages = {"com.atguigu.components"})替代
-
<context:property-placeholder引入外部配置文件使用@PropertySource({"classpath:application.properties","classpath:jdbc.properties"})替代
-
<bean 标签使用@Bean注解和方法实现
-
IoC具体容器实现选择AnnotationConfigApplicationContext对象