Spring学习笔记Day01——IoC
1.Spring概述
1.1 什么是Spring?
Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One-J2EE Development and Design中阐述的部分理念和原型衍生而来它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为J2EE应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式)轻量级开源框架。
1.2 Spring是干什么的(有什么用)?
spring可以让系统结构变得复杂难以琢磨
可以让系统臃肿性能低下
可以让使用熟练的人在菜鸟碰到莫名其妙的异常时展现自己“高深”的技术水平
刚开始写程序肯定体会不到Spring的好处,包括不接触大型的项目也体会不到Spring的好处。如果要写一个HelloWord,也可以用Spring,但是导包导半天,配置文件还要半天,而不用Spring一行代码就可以解决的问题。
那Spring到第是干嘛的呢?
我们知道在SSH框架中,Struts是用来做应用层的,它主要负责调用业务逻辑。而Hibernate是持久层框架,它主要负责与数据库的交互。Spring就是一个管理容器,它不属于J2EE应用中的任何一层,但它提供了对象依赖注入的思想,为每个层中遇到的实际问题提供了大量现成的模板类。使用这些模板类的方法很简单,大多数情况下只需要你在配置文件里配置一下就可以实现诸如事务管理或安全性控制这样的复杂问题。使用Spring的代码不依赖于框架,而依赖于接口,这对实现应用各层之间的解耦是很有利的。
1.3 Spring体系结构
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式,如图 1 所示。
图1.Spring框架的7个模块(图片来自百度百科)
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 (Web 或 EJB)、独立应用程序、测试环境之间重用。
1.4 Spring核心
Spring的核心是控制反转(IoC)和面向切面(AOP)。
1.5 Spring的优点
- 方便解耦,简化开发 (高内聚低耦合)
- Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理
- spring工厂是用于生成bean
- AOP编程的支持
- Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
- 声明式事务的支持
- 只需要通过配置就可以完成对事务的管理,而无需手动编程
- 方便程序的测试
- Spring对Junit4支持,可以通过注解方便的测试Spring程序
- 方便集成各种优秀框架
- Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
- 降低JavaEE API的使用难度
Spring 设计的核心是 org.springframework.beans 包,它的设计目标是与 JavaBean 组件一起使用。这个包通常不是由用户直接使用,而是由服务器将其用作其他多数功能的底层中介。下一个最高级抽象是 BeanFactory 接口,它是工厂设计模式的实现,允许通过名称创建和检索对象。BeanFactory 也可以管理对象之间的关系。
IoC使用案例
- 导入jar包,4个核心(beans、core、context、expression) + 1个依赖(commons-loggins…jar)。
- 目标类,提供UserSerVice接口和实现类,并获得UserSerVice实现类的实例。之前开发中,直接new一个对象即可。代码如下所示:
UerSerVice接口
public interface IUserService {
public void addUser();
}
接口实现类
public class UserServiceImpl implements IUserService {
@Override
public void addUser() {
System.out.println("add user");
}
}
测试方法
@Test
public void test01(){
IUserService ius = new UserServiceImpl();
ius.addUser();
}
将这个案例使用Spring来完成,学习spring之后,将由Spring创建对象实例–> IoC 控制反转(Inverse of Control)之后需要实例对象时,从spring工厂(容器)中获得,需要将实现类的全限定名称配置到xml文件中。
配置文件:
- 位置:任意,开发中一般在classpath(src)下
- 名称:任意如:beans.xml,开发中常用applicationContext.xml
- 内容:添加约束
测试方法:
public void test01() {
//1.之前写法
//IUserService ius = new UserServiceImpl();
//ius.addUser();
//2.spring的写法
//1 获得容器(整合Web后不用自己写)
String xmlPath = "com/hwua/a/ioc/beans.xml";
ApplicationContext context =
new ClassPathXmlApplicationContext(xmlPath);
//2获得内容 --不需要自己new,都是从spring容器获得
IUserService ius = (IUserService)
context.getBean("userServiceId");
ius.addUser();
}
2.2 DI(依赖注入)
依赖:一个对象需要使用另一个对象
注入:通过setter方法进行另一个对象实例化设置
例如:
class BookServiceImpl{
//之前开发:接口 = 实现类 (service和dao耦合)
//private BookDao bookDao = new BookDaoImpl();
//spring之后 (解耦:service实现类使用dao接口,不知道具体的实现类)
private BookDao bookDao;
setter方法
}
模拟spring执行过程:
创建service实例:BookService bookService = new BookServiceImpl()–>IoC
创建dao实例:BookDao bookDao = new BookDaoImple() –>IoC
将dao设置给service:bookService.setBookDao(bookDao)–>DI
DI使用案例
- 目标类
- 创建BookDao接口和实现类
- 创建BookService接口和实现类
- 将dao和service配置 xml文件
- 使用api测试
dao接口与实现类
public interface IBookDao {
public void addBook();
}
public class BookDaoImpl implements IBookDao {
@Override
public void addBook() {
System.out.println("add book");
}
service接口与实现类
public interface IBookService {
public abstract void addBook();
}
public class BookServiceImpl implements IBookService {
// 方式1:之前,接口=实现类
// private IBookDao bookDao = new BookDaoImpl();
// 方式2:接口 + setter
private IBookDao bookDao;
public void setBookDao(IBookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void addBook(){
this.bookDao.addBook();
}
}
配置文件
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bookServiceId" class="com.hwua.b.di.BookServiceImpl">
<!-- property:配置对象中成员属性,使用其对应的set方法注入 -->
<!-- name:类中的属性名称 -->
<!-- value:基本类型数据 int Integer -->
<!-- ref:引用数据类型 一般引用id -->
<property name="iud" ref="bookDaoId"></property>
</bean>
<bean id="bookDaoId" class="com.hwua.b.di.BookDaoImpl"></bean>
</beans>
测试方法
@Test
public void demo01(){
//从spring容器获得
String xmlPath = "com/hwua/di/beans.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
BookService bookService = (BookService) applicationContext.getBean("bookServiceId");
bookService.addBook();
}
3.bean定义
被称作 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的。bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。这些 bean 是由用容器提供的配置元数据创建的,例如,已经在先前章节看到的,在 XML 的表单中的 定义。
3.1 bean的实例化方式
bean的实例化方式有3中:
- 默认构造
- 静态工厂
- 实例工厂
3.1.1 默认构造
<bean id="" class="">
3.1.2 静态工厂
静态工厂用于生成实例化对象,所有方法必须是static
<bean id="" class="工厂全限定类名" factory-method="静态方法">
静态工厂使用案例
首先创建一个类,里面有一个普通方法
public class Dog {
public void sayHi() {
System.out.println("汪汪汪!");
}
}
然后新建一个工厂用来生成实例
public class MyBeanFactory {
/**
* 创建实例
*
* @return
*/
public static Dog getBean() {
return new Dog();
}
}
之后写配置文件beans.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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 使用静态工厂提供的方法获取实例对象 -->
<!-- 一般配合其他框架的静态工厂获取bean对象使用 -->
<!-- class 工厂的引用 -->
<!-- factory-method="getBean"方法名 -->
<bean id="dogId" class="com.spring.staticfactory.MyBeanFactory"
factory-method="getBean"></bean>
</beans>
测试方法
@Test
public void test1() {
// 1 获得容器(整合Web后不用自己写)
String xmlPath = "/com/spring/staticfactory/beans.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
// 2获得内容 --不需要自己new,都是从spring容器获得
Dog bean = (Dog) applicationContext.getBean("dogId");
bean.sayHi();
// 执行过程大致如下:
// 1.加载beans.xml配置文件
// 2.调用工厂的getBean方法获取User实例对象
// 3.根据id进行匹配 返回对象
}
3.1.3 实例工厂
实例工厂:必须先有工厂实例对象,通过实例对象创建对象。提供所有的方法都是“非静态”的。
实例工厂使用案例
工厂类
public class MyBeanFactory {
/**
* 创建实例
*
* @return
*/
public Dog getBean() {
return new Dog();
}
}
配置文件beans.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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置工厂bean(实例对象) -->
<bean id="myFactoryId" class="com.spring.shilifactory.MyBeanFactory"></bean>
<!-- 配置dogbean(对象)-获取依赖于工厂bean(对象) -->
<bean id="dogId" factory-bean="myFactoryId" factory-method="getBean"></bean>
</beans>
测试方法
@org.junit.Test
public void test2() {
String xmlPath = "/com/spring/shilifactory/beans.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
Dog bean = (Dog) applicationContext.getBean("dogId");
bean.sayHi();
}
3.2 bean的种类
- 普通bean:之前操作的都是普通bean。
<bean id="" class="A">,spring直接创建A实例,并返回 - FactoryBean:是一个特殊的bean,具有工厂生成对象能力,只能生成特定的对象。
- bean必须使用 FactoryBean接口,此接口提供方法 getObject() 用于获得特定bean。
先创建FB实例,使用调用getObject()方法,并返回方法的返回值
FB fb = new FB();
return fb.getObject();
BeanFactory 和 FactoryBean 对比?
BeanFactory:工厂,用于生成任意bean。
FactoryBean:特殊bean,用于生成另一个特定的bean。例如:ProxyFactoryBean ,此工厂bean用于生产代理。获得代理对象实例。
BeanFactory和FactoryBean其实没有什么比较性的,只是两者的名称特别接近,所以有时候会拿出来比较一番3.3 bean的作用域
当在 Spring 中定义一个 时,你必须声明该 bean 的作用域的选项。例如,为了强制 Spring 在每次需要时都产生一个新的 bean 实例,你应该声明 bean 的作用域的属性为 prototype。同理,如果你想让 Spring 在每次需要时都返回同一个bean实例,你应该声明 bean 的作用域的属性为 singleton。
Spring 框架支持以下五个作用域,如果你使用 web-aware ApplicationContext 时,其中三个是可用的。
表3-1 bean的五个作用域
| 作用域 | 说明 |
| singleton | 该作用域将 bean 的定义的限制在每一个 Spring IoC 容器中的一个单一实例(默认)。 |
| prototype | 该作用域将单一 bean 的定义限制在任意数量的对象实例。 |
| request | 该作用域将 bean 的定义限制为 HTTP 请求。只在 web-aware Spring ApplicationContext 的上下文中有效。 |
| session | 该作用域将 bean 的定义限制为 HTTP 会话。 只在web-aware Spring ApplicationContext的上下文中有效。 |
| global-session | 该作用域将 bean 的定义限制为全局 HTTP 会话。只在 web-aware Spring ApplicationContext 的上下文中有效。 |
3.3.1 singleton 作用域
如果作用域设置为 singleton,那么 Spring IoC 容器刚好创建一个由该 bean 定义的对象的实例。该单一实例将存储在这种单例 bean 的高速缓存中,以及针对该 bean 的所有后续的请求和引用都返回缓存对象。
默认作用域是始终是 singleton,但是当仅仅需要 bean 的一个实例时,你可以在 bean 的配置文件中设置作用域的属性为 singleton,如下所示:
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="singleton">
<!-- collaborators and configuration for this bean go here -->
</bean>
3.3.2 prototype 作用域
如果作用域设置为 prototype,那么每次特定的 bean 发出请求时 Spring IoC 容器就创建对象的新的 Bean 实例。一般说来,满状态的 bean 使用 prototype 作用域和没有状态的 bean 使用 singleton 作用域。也就是说没执行一次getBean就会获得一个新的实例。
为了定义 prototype 作用域,你可以在 bean 的配置文件中设置作用域的属性为 prototype,如下所示:
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
3.4 bean生命周期
- instantiate bean对象实例化
- populate properties 封装属性
- 如果Bean实现BeanNameAware 执行 setBeanName
- 如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
- 如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization
- 如果Bean实现InitializingBean 执行 afterPropertiesSet
- 调用
指定初始化方法 init - 如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization
- 执行业务处理
- 如果Bean实现 DisposableBean 执行 destroy
- 调用
指定销毁方法 customerDestroy
bean的生命周期有以上11个步骤。其中主要的是初始化和销毁两个生命周期回调方法,它们在bean的初始化和销毁时是必须的。
3.4.1 初始化和销毁
目标方法执行前后执行后,将进行初始化或销毁。
<bean id="" class="" init-method="初始化方法名称" destroy-method="销毁的方法名称">
例子
创建一个类
public class Dog {
public void sayHi() {
System.out.println("汪汪汪!");
}
public void init() {
System.out.println("初始化");
}
public void destroy() {
System.out.println("销毁了");
}
}
配置文件beans.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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dogId" class="com.spring.beanlife.Dog" init-method="init"
destroy-method="destroy"></bean>
</beans>
测试方法
@org.junit.Test
public void test() {
String xmlPath = "/com/spring/beanlife/beans.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
Dog bean = (Dog) applicationContext.getBean("dogId");
bean.sayHi();
// 要求:1.容器必须close,销毁方法执行; 2.必须是单例的
// applicationContext.getClass().getMethod("close").invoke(applicationContext);
// * 此方法接口中没有定义,实现类提供
((AbstractApplicationContext) applicationContext).close();
}
}
3.4.2 bean后置处理器(BeanPostProcessor)
BeanPostProcessor 接口定义回调方法,你可以实现该方法来提供自己的实例化逻辑,依赖解析逻辑等。你也可以在 Spring 容器通过插入一个或多个 BeanPostProcessor 的实现来完成实例化,配置和初始化一个bean之后实现一些自定义逻辑回调方法。
spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after() 。
你可以配置多个 BeanPostProcesso r接口,通过设置 BeanPostProcessor 实现的 Ordered 接口提供的 order 属性来控制这些 BeanPostProcessor 接口的执行顺序。
BeanPostProcessor 可以对 bean(或对象)实例进行操作,这意味着 Spring IoC 容器实例化一个 bean 实例,然后 BeanPostProcessor 接口进行它们的工作。
例子
编写一个类实现BeanPostProcessor接口
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("前方法 : " + beanName);
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("后方法 : " + beanName);
// bean 目标对象
// 生成 jdk 代理
Proxy.newProxyInstance(MyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("------开启事务");
Object object = method.invoke(bean, args);
System.out.println("------提交事务");
return object;
}
});
return bean;
}
}
接着使用上一节中的Dog类,在配置文件中加入
<bean class="com.spring.beanlife.MyBeanPostProcessor"></bean>
测试方法
@org.junit.Test
public void test() {
String xmlPath = "/com/spring/beanlife/beans.xml";
AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
Dog bean = (Dog) applicationContext.getBean("dogId");
bean.getMessage();
// 要求:1.容器必须close,销毁方法执行; 2.必须是单例的
// applicationContext.getClass().getMethod("close").invoke(applicationContext);
// * 此方法接口中没有定义,实现类提供
applicationContext.registerShutdownHook();
((AbstractApplicationContext) applicationContext).close();
}
4.属性依赖注入
依赖注入的方式有手动装配和自动装配。手动装配又可分为基于xml文件的装配和基于注解的装配。基于xml装配又分为基于构造函数和基于设值函数两种。
4.1 基于构造函数注入
目标类
public class User {
private Integer uid;
private String username;
private Integer age;
public User(Integer uid, String username) {
super();
this.uid = uid;
this.username = username;
}
public User(String username, Integer age) {
super();
this.username = username;
this.age = age;
}
}
spring配置
<!-- 构造方法注入
* <constructor-arg> 用于配置构造方法一个参数argument
name :参数的名称
value:设置普通数据
ref:引用数据,一般是另一个bean id值
index :参数的索引号,从0开始 。如果只有索引,匹配到了多个构造方法时,默认使用第一个。
type :确定参数类型
例如:使用名称name
<constructor-arg name="username" value="jack"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
例如2:【类型type 和 索引 index】 常用
<constructor-arg index="0" value="1"></constructor-arg>
<constructor-arg index="1" value="2"></constructor-arg>
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
-->
<bean id="userId" class="com.hwua.xml.a_constructor.User" >
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
</bean>
4.2 设置值注入(setter注入)
<bean id="personId" class="com.hwua.xml.b_setter.Person">
<property name="pname" value="罗玉凤"></property>
<property name="age">
<value>1234</value>
</property>
<property name="homeAddr" ref="homeAddrId"></property>
<property name="companyAddr">
<ref bean="companyAddrId"/>
</property>
</bean>
<bean id="homeAddrId" class="com.hwua.xml.b_setter.Address">
<property name="addr" value="美国"></property>
<property name="tel" value="911"></property>
</bean>
<bean id="companyAddrId" class="com.hwua.xml.b_setter.Address">
<property name="addr" value="上海"></property>
<property name="tel" value="110"></property>
</bean>
4.3集合注入
上面通过value属性来配置基本数据类型进bean中。如果想传多个值那么怎么办呢?对于这种情况Spring提供了四个集合类型和一个数组来配置元素。分别为:String[],List
<!--
集合的注入都是给<property>添加子标签
数组:<array>
List:<list>
Set:<set>
Map:<map> ,map存放k/v 键值对,使用<entry>描述
Properties:<props> <prop key=""></prop> 【】
普通数据:<value>
引用数据:<ref>
-->
<bean id="collDataId" class="com.hwua.xml.e_coll.CollData" >
<property name="arrayData">
<array>
<value>罗玉凤</value>
<value>芙蓉</value>
<value>白百合</value>
<value>马蓉</value>
</array>
</property>
<property name="listData">
<list>
<value>马云</value>
<value>马化腾</value>
<value>马明哲</value>
</list>
</property>
<property name="setData">
<set>
<value>罗玉凤</value>
<value>谢霆锋</value>
<value>陈冠希</value>
</set>
</property>
<property name="mapData">
<map>
<entry key="jack" value="杰克"></entry>
<entry>
<key><value>rose</value></key>
<value>肉丝</value>
</entry>
</map>
</property>
<property name="propsData">
<props>
<prop key="高富帅">嫐</prop>
<prop key="白富美">嬲</prop>
<prop key="男屌丝">挊</prop>
</props>
</property>
</bean>
4.4 基于注解的配置
从 Spring 2.5 开始就可以使用注解来配置依赖注入。而不是采用 XML 来描述一个 bean 连线,你可以使用相关类,方法或字段声明的注解,将 bean 配置移动到组件类本身。
在 XML 注入之前进行注解注入,因此后者的配置将通过两种方式的属性连线被前者重写。
<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
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 组件扫描,扫描含有注解的类 -->
<context:component-scan base-package="com.hwua.annotation.a_ioc"></context:component-scan>
</beans>
5.总结
第一天的主要内容为spring两大核心中的IoC。通过今天的学习,知道了IoC其实是一个容器,用来管理bean的容器。那么bean是什么呢,有道翻译为“毫无价值的东西”…其实bean可以理解为对象,IoC是一个管理对象的容器,这样貌似挺合理的。