Spring DI(IOC)

注释用法

@Required

用于setter方法上,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个BeanInitializationException 异常。

public class Student{
  private String name;
  private int age;

  @Required
  public void setAge(Integer age) {
     this.age = age;
  }
  public Integer getAge() {
     return age;
  }
  @Required
  public void setName(String name) {
     this.name = name;
  }
  public String getName() {
     return name;
  }
}
//xml配置文件里没有配置age这个属性,会报BeanInitializationException的异常。
<context:annotation-config/>
<bean id="student" class="Student">
  <property name="name" value="lph"/>
</bean>

@Autowired

默认按照类型方式进行bean匹配
对属性注释,用来替代setter方法
对setter方法注释
对构造函数注释

public class Customer 
{
   @Autowired        //对属性注释
	private Person person;
	private int type;
	private String action;
	
   @Autowired        //对setter方法注释
   public setPerson(Person person){
       this.persion=persion;
   }
	
	@Autowired       //对构造函数注释
	public Customer(Person person) {
		this.person = person;
	}
}
//@Autowired注解是通过匹配数据类型自动装配Bean。	
	<bean id="CustomerBean" class="com.x'x'x'x.common.Customer">
		<property name="action" value="buy" />
		<property name="type" value="1" />
	</bean>

	<bean id="PersonBean" class="com.x'x'x'x.common.Person">
		<property name="name" value="xx" />
		<property name="address" value="address ABC" />
		<property name="age" value="29" />
	</bean>	

使用扫描器来扫描包,省去在配置文件里配置相关bean

<context:component-scan base-package="xxx.xxxx.xxxxxx.xxxx"/>

依赖检查
默认情况下,@Autowired将执行相关检查,以确保属性已经装配正常。当Spring无法找到匹配的Bean装配,它会抛出异常。要解决这个问题,可以通过 @Autowired 的“required”属性设置为false来禁用此检查功能。

public class Customer 
{
	@Autowired(required=false)//即使没有匹配的bean,spring也不会报错
	private Person person;
	private int type;
	private String action;
	//getter and setter methods
}

@Qualifier

创建多个具有相同类型的 bean 时,想要用一个属性只为它们其中的一个bean进行装配,使用 @Qualifier 注释和 @Autowired 注释通过指定哪一个真正的 bean 将会被装配来消除混乱。

public interface Parent(){
	public void iAmParent(){}
}
@Component
public class mother implements Parent{
	public void iAmParent(){
		.......
}
@Component
public class father implements Parent{
	public void iAmParent(){
		.......
	}
}
@Service
public class SequenceServiceImpl implements SequenceService {
	
	//此处会报错,因为parent有两个实现类father和mother
	@Resource
	private Parent parent;
}

此时我们可以用@Qualifier

@Service
public class SequenceServiceImpl implements SequenceService {

//使用@Qualifier指定bean
@Qualifier(name="father")
 private Parent parent;
}

@Resource

JSR-250规范定义的注解
和@Autowired作用类似,只不过@Autowired是byType的方式自动注入,@Resource默认自动注入的方式为byName
@Resource装配顺序:
 1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
 2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
 3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
 4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;

@Bean @Configuration @Import 来代替xml配置文件

<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-3.0.xsd">
 
	<bean id="helloBean" class="com.xxx.hello.impl.HelloWorldImpl">		
</beans>

**等效于以下JavaConfig的配置:**

@Configuration
public class AppConfig {	
    @Bean(name="helloBean")
    public HelloWorld helloWorld() {
        return new HelloWorldImpl();
    }	
}
<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-2.5.xsd">
 
	<import resource="config/customer.xml"/>
    <import resource="config/scheduler.xml"/>
 
</beans>

**效于 @Import 功能**

@Configuration
@Import({ CustomerConfig.class, SchedulerConfig.class })
public class AppConfig {}

Spring自动扫描组建

启用Spring组件扫描功能。

<context:component-scan base-package="xx.xxx.xxxx"/>

使用@Component注释来表示这是类是一个自动扫描组件。

@Component
public class CustomerDAO 
{
	@Override
	public String toString() {
		return "Hello , This is CustomerDAO";
	}	
}

DAO层,添加@Component,表明这也是一个自动扫描组件。

@Component
public class CustomerService 
{
	@Autowired
	CustomerDAO customerDAO;

	@Override
	public String toString() {
		return "CustomerService [customerDAO=" + customerDAO + "]";
	}
} 

要创建组件的自定义名称,你可以这样自定义名称:

@Service("AAA")
public class CustomerService 

自动扫描的组建类型(都是@Component的意思),对class注解

@Repository – 表示在持久层DAO组件。
@Service – 表示在业务层服务组件。
@Controller – 表示在表示层控制器组件。
@Component – 指示自动扫描组件。(不属于以上三者的时候使用)

Spring过滤器组件自动扫描

//include-filter 包含
<context:componnet-scan base-package="xx.xx.xxx">
 <context:include-filter type="regex" expression="xx.xxx.*DAO.*">
</context>
//exclude-filter 不包含

通过配置文件来配置Spring

基于构造函数的依赖注入

注入class

public class demo{
    Test test;
    public void demo(Test test){
        this.test=test;
    } }

<bean id="demo" class="demo">
       <constructor-args ref="test" />  
       <constructor-args ref="test2" />
</bean>

//声明2个class的bean
 <bean id="test" class="test" />
 <bean id="test2" class="test2" />

注入其他类型的值

public class demo{    
    public void demo(String str,int num){
        .....
    } }

<bean id="demo" class="demo">
   <constructor-args type="java.lang.String" value="axxxx" />
   <constructor-args type="int" value="1" />
</bean>

通过索引注入

<bean id="demo" class="demo">
  <constructor-args index="0" value="axxxx" /> 
  <constructor-args index="1" value="1" />
</bean>

基于设置函数的注入

public class demo{
   public void test(String str){
   .......
   }
} 
<bean id="demo" class="demo">
  <property name="str" value="this is a String" />
</bean> 

注入集合

public class demo{    
	List array;
	HashMap map;
	Porperties prop; 
} 
//注入list
<bean id="demo" class="demo">
   <property name="array">
    <list>
	      <value>1</value>
	      <value>2</value>
    <list>
  </property> 
//注入map
<property name="map">
   <map>
       <entry key="1" value="a1"/>
       <entry key="2" value="a2"/>
   </map>
</property> 
//注入属性
<property name="prop">
   <props>
      <prop key="key1">xxx</prop>
      <prop key="key2">bbb</prop>         
   </props>
</property> 

注入空值null

<bean><property name="asd"><null/></property></bean>

在Spring框架中,当一个类包含多个构造函数带的参数相同,它总是会造成构造函数注入参数类型歧义的问题。
为了解决这个问题,应该为构造函数指定的确切数据类型,通过像这样类型的属性:

<bean id="CustomerBean" class="com.xxx.common.Customer">
	
		<constructor-arg type="java.lang.String">
			<value>xxx</value>
		</constructor-arg>
		
		<constructor-arg type="java.lang.String">
			<value>188</value>
		</constructor-arg>
		
		<constructor-arg type="int">
			<value>28</value>
		</constructor-arg>		
	</bean>
</beans>

自动装配

1. 默认的模式
这是默认的模式,你需要通过 ‘ref’ 属性来连接 bean。

<bean id="customer" class="com.yiibai.common.Customer">
       <property name="person" ref="person" />
</bean>
<bean id="person" class="com.yiibai.common.Person" />

2. 按属性名称自动装配’
按属性名称自动装配。在这种情况下,由于对“person” bean的名称是相同于“customer” bean 的属性(“person”)名称,所以,Spring会自动通过setter方法将其装配 – “setPerson(Person person)“.

<bean id="customer" class="com.yiibai.common.Customer" autowire="byName" />	
<bean id="person" class="com.yiibai.common.Person" />

3. 按属性的数据类型自动装配
通过按属性的数据类型自动装配Bean。在这种情况下,由于“Person” bean中的数据类型是与“customer” bean的属性>(Person对象)的数据类型一样的,所以,Spring会自动通过setter方法将其自动装配。– “setPerson(Person person)“.

<bean id="customer" class="com.yiibai.common.Customer" autowire="byType" />
<bean id="person" class="com.yiibai.common.Person" />

注入日期到bean属性

以下写法会报错

public class Customer {
	Date date;
	public Date getDate() {
		return date;
	}
	public void setDate(Date date) {
		this.date = date;
	}
}
<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-2.5.xsd">

	<bean id="customer" class="Customer">
		<property name="date" value="2015-12-31" />//直接传string类型的值给value
	</bean>
</beans>

正确的方法

factory-bean

<bean id="customer" class="Customer">
	<property name="date">
       <bean factory-bean="dataFormat" factory-method="parse">
           <constructor-arg value="2015-12-31" />
       </bean>
   </property>
</bean>

CustomDateEditor

	<bean id="dateEditor" class="org.springframework.beans.propertyeditors.CustomDateEditor">
		<constructor-arg>
			<bean class="java.text.SimpleDateFormat">
				<constructor-arg value="yyyy-MM-dd" />
			</bean>
		</constructor-arg>
		<constructor-arg value="true" />
	</bean>

	<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
		<property name="customEditors">
			<map>
				<entry key="java.util.Date">
					<ref local="dateEditor" />
				</entry>
			</map>
		</property>
	</bean>

	<bean id="customer" class="Customer">
		<property name="date" value="2015-12-31" />
	</bean>

PropertyPlaceholderConfigurer

在声明bean配置文件和提供一个PropertyPlaceholderConfigurer映射到“database.properties”属性文件。

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="location">
		<value>database.properties</value>
	</property>
</bean>
<bean id="dataSource" 
       class="org.springframework.jdbc.datasource.DriverManagerDataSource">
   <property name="driverClassName" value="${jdbc.driverClassName}" />
   <property name="url" value="${jdbc.url}" />
	<property name="username" value="${jdbc.username}" />
	<property name="password" value="${jdbc.password}" />
</bean>

Bean的切面处理

init-method 指定一个方法,在实例化 bean 时,调用该方法。
destroy-method 指定一个方法,从容器中移除 bean 之后,调用该方法。
singleton 和 prototype的区别( http://wiki.jikexueyuan.com/project/spring/bean-scopes.html)

<bean id="..." class="...." 
init-method="..." (destroy-method)
scope="..."
lazy-init="..." 
destroy-method="..." />
public example implements InitializingBean{
 //实现InitializingBean接口,bean 初始化时可调用的初始化方法
  public void do(){}
}

public example implements DisposableBean{
 //实现DisposableBean接口,bean 销毁时可调用的初始化方法
  public void do(){}
}

两种后处理方法

Bean后处理器
Bean后处理器会在Bean实例创建成功之后,对Bean实例进行进一步的增强处理。
Bean后处理器必须实现BeanPostProcessor接口,同时必须实现该接口的两个方法。

public example implements BeanPostProcessor{

   //该方法的第一个参数是系统即将进行后处理的Bean实例,第二个参数是该Bean的配置id
   Object postProcessBeforeInitialization(Object bean, String name) throws BeansException: 
   Object postProcessAfterinitialization(Object bean, String name) throws BeansException: 
}

容器后处理器
容器后处理器必须实现BeanFactoryPostProcessor接口,并实现该接口的一个方法

public example implements BeanFactoryPostProcessor{ 
   postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory){}
}

Bean可以继承

<bean id="parent" class=".....">
 <property name="test" value="tttt" />
</bean>

<bean id="child" class="....." parent="parent">
 <property name="test1" value="tttt" />
</bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值