概念
IOC(Inversion of Control)
其思想是反转资源获取的方向. 传统的资源查找方式要求组件向容器发起请求查找资源. 作为回应, 容器适时的返回资源. 而应用了 IOC 之后, 则是容器主动地将资源推送给它所管理的组件, 组件所要做的仅是选择一种合适的方式来接受资源. 这种行为也被称为查找的被动形式
DI(Dependency Injection) — IOC 的另一种表述方式
即组件以一些预先定义好的方式(例如: setter 方法)接受来自如容器的资源注入. 相对于 IOC 而言,这种表述更直接
通过反射机制配置Bean
注入的方式
- 构造函数方式 (类中需要带参数的构造函数)
<constructor-arg></constructor-arg>
- 属性方式 (类中需要无参数的构造函数)
<property></property>
abstract属性为true的时候,IOC容器不会实例化对象,如果value属性含有特殊字符,需要使用<![CDATA[]]>包裹起来
集合
- 属性为list集合
<property name="group"> <list> <ref bean="developer"></ref> <ref bean="developer"></ref> </list> </property>
- 属性为props
<property name="adminEmails"> <props> <prop key="administrator">administrator@example.org</prop> <prop key="support">support@example.org</prop> <prop key="development">development@example.org</prop> </props> </property>
- 属性为map
<property name="someMap"> <map> <entry key="an entry" value="just some string"/> <entry key ="a ref" value-ref="myDataSource"/> </map> </property>
- 属性为set
<property name="someSet"> <set> <value>just some string</value> <ref bean="myDataSource" /> </set> </property>
通过工厂方法配置Bean
静态工厂方法
Factory类本身不需要实例化,这个Factory类中提供了1个静态方法来生成bean对象
public class StaticAddressFactory {
private static Map<String, Address> addressMap = new HashMap<String, Address>() ;
static {
addressMap.put("JINAN", new Address("JINAN", "SHILIHE"));
addressMap.put("QINGDAO", new Address("QINGDAO", "SIFANG"));
}
public static Address getAddress(String name){
return addressMap.get(name);
}
}
实例工厂方法
Factory类本身需要实例化
public class SigletonAddressFactory {
public Map<String, Address> getAddressMap() {
return addressMap;
}
public void setAddressMap(Map<String, Address> addressMap) {
this.addressMap = addressMap;
}
private Map<String, Address> addressMap = new HashMap<String, Address>() ;
public Address getAddress(String name){
return this.addressMap.get(name);
}
}
Factory Bean模式配置Bean
Factory Bean模式
比工厂方法模式更常见,Factory Bean工厂类必须实现spring提供的FactoryBean的接口
重写以下三个方法:
- getObject()
这个就是你想利用工厂类生产的bean对象, 通常在里面new 1个 对象就ok - getObjectType()
你必须指明上面bean的对象的class - isSingleton
这个方法决定了这个bean是否单例的
案例
public class MyAddressFactory implements FactoryBean<Address> {
private String city;
private String street;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Override
public Address getObject() throws Exception {
return new Address(this.city, this.street);
}
@Override
public Class<?> getObjectType() {
return Address.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
通过FactoryBean方式,从IOC容器里面bean,通过FactoryBean的getObject返回指定的bean,property: MyAddressFactory的属性设置
通过注解方式注入Bean
- 组件扫描(component scanning): Spring 能够从 classpath 下自动扫描, 侦测和实例化具有特定注解的组件.
- 特定组件包括:
@Component: 基本注解, 标识了一个受 Spring 管理的组件
@Respository: 标识持久层组件
@Service: 标识服务层(业务层)组件
@Controller: 标识表现层组件 -
对于扫描到的组件, Spring 有默认的命名策略: 使用非限定类名, 第一个字母小写. 也可以在注解中通过 value 属性值标识组件的名称
-
在组件类上使用了特定的注解之后, 还需要在 Spring 的配置文件中声明 <context:component-scan> :
base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类.
当需要扫描多个包时, 可以使用逗号分隔.-
如果仅希望扫描特定的类而非基包下的所有类,可使用 resource-pattern 属性过滤特定的类
- <context:include-filter> 子节点表示要包含的目标类
- <context:exclude-filter> 子节点表示要排除在外的目标类
- <context:component-scan> 下可以拥有若干个 <context:include-filter> 和 <context:exclude-filter> 子节点
-
Scope("prototype")
当bean增加注解@Scope("prototype"),那么就是获得的多实例的bean
命名策略
对于扫描到的组件, Spring 有默认的命名策略:
- 使用非限定类名, 第一个字母小写.
- 也可以在注解中通过 value 属性值标识组件的名称
<!--在context中声明需要检测的bean目录,同时会检测目录的子目录-->
<context:component-scan base-package="com.annotation"></context:component-scan>
<!--
扫描base-package目录子的某一个子目录,可以利用resource-pattern
<context:component-scan base-package="com.annotation" resource-pattern="子目录/*.class"></context:component-scan>
-->
bean的作用域
singleton
单例模式
prototype
每次取出的bean对象都需要实例化
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/191499.html