spring 是一个
IOC(DI) 和
AOP 容器框架---
依赖注入(DI)、面向切面编程(AOP)
IOC :反转资源获取的方向---容器主动地将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源
DI : 组件以一些预先定义好的方式 (例如 setter方法)接受来自如容器的资源注入
前生:
①分离接口与实现
②采用工厂设计模式
③采用反转控制---要什么,就放一个容器,别人就会把你要的东西放进容器里,而不是自己去要
准备
①导入jar包
②在类的路径下配置bean的配置文件
配置bean:
配置形式:基于 xml 文件的方式、基于 注解的方式
Bean的配置方式:通过全类名(反射)、通过工厂方法(静态工厂方法 & 实例工厂方法)、FactoryBean
依赖注入的方式:属性注入;构造器注入
---类的全类名(反射--无参构造器),通过 id 来标识容器中的 bean。id唯一
ApplicationContext 是 BeanFactory 的
子接口,它就是指 IOC 容器。BeanFactory 是spring面向spring本身,而 ApplicationContext 是面向 spring框架的开发者。
ApplicationContext 的主要实现类:
ClassPathXmlApplicationContext:从类路径下加载配置文件
FileSystemXmlApplicationContext : 从文件系统中加载配置文件
获取Bean
通过 id 获取,如果通过 类名获取,当有多个同类不同的bean时,就会报错,因为不知道是哪个。
依赖注入方式:
属性注入:通过setter方法注入 ---最常用的注入方式。<property name="" value=“”>
---
在获取了配置文件后,当配置是通过属性注入时,会先调用无参构造器和其对应的 setter方法.
构造器注入:<constructor-arg value="" ></constructor-arg > --- 按照有参构造器的参数依次配置,当构造器产生歧义时,意思就是可以转换类型时,
可以用
type 来指定参数的类型以区分重载构造器.----在获取了配置文件后,当配置是通过构造器注入时
,会调用其对应的有参构造器进行赋值.也可以用 index来指定构造器的顺序,默认是 0,1,2.。。
只要是在配置文件中配置了,就会依次调用对应的构造器进行初始化!!反注入
可以通过value标签来设定属性值
,用 <![CDATA【】]> 来包含特殊字符
<
value
>
<![CDATA[
<hehe^>
]]>
</
value>
bean 的 引用配置 -- 成员变量是一个类,可以通过 ref属性 或者 其子标签 <ref> 来指定
内部bean --- 不能被外部引用,只能在内部引用
当要给引用类型的成员变量赋值为 null时,需要用 <null/>
也可以通过 person.name 的级联方式赋值,但是前提是要先构造出person 对象,即属性要先初始化后才能级联赋值,否则会有异常,和 Struts2 不同
集合属性
Map集合
<map>
<entry key = ""
value-ref = ""></entry> -- 引用类型;如果是基本类型就用 value 属性
</map>
Properties
<props>
<prop key = ""> value </prop>
<prop key = ""> value </prop>
</props>
配置独立的集合 bean ,以供多个bean 进行引用。需要导入 util 的命名空间
P 命名空间,先导入 p 命名空间 。可以通过 P 命名空间为 bean 的属性赋值,相对于传统的配置方式更加的便捷
通过工厂方法(静态方法 & 实例工厂方法)配置Bean
① 通过静态方法配置,需要把方法声明为 static,通过constructor-arg 给方法传入参数构造bean。通过直接调用方法构造出 bean
②
通过实例工厂方法配置bean
实例工厂方法:创建工厂本身,再通过调用工厂的实例方法返回 bean的实例
通过 FactoryBean 配置 bean
①实现类需要实现 FactoryBean的接口
② class:指向 FactoryBean 的实现类
③ property:配置 FactoryBean中的属性
实际返回的实例却是 FactoryBean 的 getObject()方法返回的对象
基于注解配置 方式
组件扫描:spring能够从classpath 下自动扫描,侦测和实例化具有特定注解的组件
特定组件:
①@Component :基本注解
②@Repository:持久层组件
③@Service:标识业务层组件
④@Controller:标识表现层组件
对于扫描的组件,需要使用非限定类名,第一个字母小写,也可以在注解中通过value属性值标识组件的名称,例:@Repository(“name”)
--base-package:指定需要扫描的包以及其子包,当多个包时需要使用逗号分隔
--
resource-pattern:过滤特定的类 --packageName/*.
class
context:component 下的 exclude-filter 和 include-filter 子节点 分别表示 排除在外的目标类 和 包括在内的目标类,可以有若干个
注意:当使用 include-filter时需要 把其父节点的
use-default-filters 设置为false,不然全部被注解的类都会由IOC容器管理
其
type 属性的取值可以为
①
annotation :对目标类是否标注了某个注解进行过滤,其 expression的取值是那四种的全类名
②
assignable:对目标是否继承或扩展某个特定的类进行过滤,其expression的取值是对应的父类或接口的全类名
使用@Autowired 自动装配 Bean
1.普通字段 和 一切具有 参数的方法都可以使用 @
Autowired 注解。
2.所有使用此注解的属性 都需要被设置,如果spring找不到匹配的bean 装配属性时,就会抛出异常。如果想要其值为null,可以设置 @Autowired 的required 属性为false,@Autowired(required = false)
3.当作用于 数组 或者 集合的属性上,spring会把所有的bean 进行自动装配
4.当用在 Map上时,若 key 的类型为 String,则spring将自动封装与之Map值类型兼容的bean ,此时 bean 的名称作为 key
5.
当同类型有多个bean 符合时(父类对象指向子类的情况),通过类型的自动装配将无法工作
解决办法:
①通过设置 注解的名字的值与 需要对应的属性名一致
②可以通过
@Qualifier ("name")提供 bean 的名称(首字母小写的命名规则)