Spring - 初始化bean

28 篇文章 0 订阅

对于Spring框架来说,控制反转(Inversion of Control)和依赖注入(Dependency injection)是其核心,这里通过一个 bean 初始化的过程来理解一下IoC和DI的概念。

# URL
http://www.springsource.org/download/community 
http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/ 

# 依赖 jar
commons-logging-1.1.3.jar
spring-beans-3.2.3.RELEASE.jar
spring-context-3.2.3.RELEASE.jar
spring-core-3.2.3.RELEASE.jar
spring-expression-3.2.3.RELEASE.jar

# 一个最简单的 spring 配置文件 

# src/spring.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="person" class="org.demo.bean.Person" />
    
</beans>
# Java 代码
package org.demo.bean;

import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class Person {

	private boolean propBool;
	private byte propByte;
	private short propShort;
	private int propInt;
	private long propLong;
	private float propFloat;
	private double propDouble;
	private String propStr;
	private Set<String> propSet;
	private Map<String, String> propMap;
	private Properties props;
	private String propSystemProp;
	private String propSystemEnv;
	/** get set methods */
}
# 测试代码
package org.demo;

import org.demo.bean.Person;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

	public static void main(String[] args) {
		AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
		Person p1 = ctx.getBean(Person.class);     // 通过类型来获取 bean
		Person p2 = (Person)ctx.getBean("person"); // 通过 id来获取 bean
		System.out.println(p1);
		System.out.println(p2);
	}
}
# 这里获取到的 p1、p2 是同一个实例,因为 spring 容器中的 bean 默认是单例,也就是 singleton,如果需要每次调用 getBean 得到的都是不同的实例,则需要将 bean 的 scope 属性设置成 prototype ,如下:
<bean id="person" class="org.demo.bean.Person" scope="prototype" />

# 设置 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" 
    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:property-placeholder />
    
    <bean id="person" class="org.demo.bean.Person">
        <property name="propBool" value="true" />
        <property name="propByte" value="1" />
        <property name="propShort" value="2" />
        <property name="propInt" value="3" />
        <property name="propLong" value="4" />
        <property name="propFloat" value="5.0" />
        <property name="propDouble" value="6.2" />
        <property name="propStr" value="zhangSan" />
        <property name="propSet">
            <set>
                <value>10</value>
                <value>12</value>
            </set>
        </property>
        <property name="propMap">
            <map>
                <entry key="key1" value="value1" />
                <entry key="key2" value="value2" />
            </map>
        </property>
        <property name="props">
            <props>
                <prop key="propKey1">propValue1</prop>
                <prop key="propKey2">propValue2</prop>
            </props>
        </property>
        <property name="propSystemProp" value="${java.io.tmpdir}" />
        <property name="propSystemEnv" value="${JAVA_HOME}" />
    </bean>
    
</beans>
# 注意:通过 ${propertyName} 这种方式不仅可以引用JVM的系统属性(在JVM启动的时候通过参数 -DpropertyName=propertyValue 进行设置),还可以引用操作系统的环境变量(例如 windows 中的 系统属性 -> 高级 -> 环境变量 -> 系统变量)。使用 ${...} 时需要配置有 <context:property-placeholder />,否则${...} 将当成普通字符串进行处理。

# 注入依赖对象
# 方案一(通过<property> 元素来注入依赖对象)

package org.demo.service;

import org.demo.bean.Person;

public class PersonService {

	private Person person;

	/** get set methods */
}
<?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="person" class="org.demo.bean.Person">
        <property name="propStr" value="zhangSan" />
    </bean>
    
    <bean id="personService" class="org.demo.service.PersonService" >
        <property name="person" ref="person" />
    </bean>
    
</beans>
# 方案二(通过@Autowired注解来注入依赖对象)
package org.demo.service;

import org.demo.bean.Person;
import org.springframework.beans.factory.annotation.Autowired;

public class PersonService {
    
	@Autowired
	private Person person;
    
	/** get set methods */
}
<?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
       http://www.springframework.org/schema/context/spring-context.xsd" >
    
    <!-- 这里表示启用注解,例如: -->
    <!--  @Repository、@Service、@Controller、@Component、@Autowired、@Resource -->
    <context:annotation-config />
    
    <bean id="person" class="org.demo.bean.Person">
        <property name="propStr" value="zhangSan" />
    </bean>
    
    <bean id="personService" class="org.demo.service.PersonService" />
    
</beans>
# 方案三(通过@Resource注解来注入依赖对象)
	@Resource
	private Person person;
# 注入 ApplicationContext
# 方案一(通过 @Autowired/@Resource 注解来注入)
	@Resource
	// @Autowired
	private ApplicationContext ctx;
# 方案二(通过实现接口 ApplicationContextAware 来注入)
package org.demo.service;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class PersonService implements ApplicationContextAware {
    
	private ApplicationContext ctx;
    
	@Override
	public void setApplicationContext(ApplicationContext pCtx)
			throws BeansException {
		this.ctx = pCtx;
	}
	
	/** get set methods */
}

其他 Aware 接口请参阅:http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#aware-list  

# bean 的生命周期 - 在初始化 bean 的过程中执行一段自定义的代码
# 方案一(通过@PostConstruct 注解来实现)

	@PostConstruct
	public void postConstruct() {
		System.out.println("-- postConstruct --");
	}
# 方案二(通过接口 InitializingBean 来实现)
public class PersonService implements InitializingBean{
    
	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("-- afterPropertiesSet --");
	}
}
# 方案三(通过在 spring 配置文件中指定一个初始化方法来实现)
    <bean id="personService" 
          class="org.demo.service.PersonService" init-method="init" />
或者
<?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
       http://www.springframework.org/schema/context/spring-context.xsd" 
    default-init-method="init2">
    <!-- ... -->
</beans>

# bean 的生命周期 - 在销毁 bean 之前执行一段自定义的代码
# 与初始化过程中对应的依次为:@PreDestroy注解、DisposableBean接口、destroy-method/default-destroy-method

# bean 的生命周期 - SmartLifecycle

package org.demo.service;

import org.springframework.context.SmartLifecycle;

public class PersonService implements SmartLifecycle {
    
	private boolean isRunning = false;
	
	@Override
	public boolean isAutoStartup() {
		System.out.println("-- isAutoStartup --");
		return true;
	}
	
	@Override
	public int getPhase() {
		System.out.println("-- getPhase --");
		return -1;
	}
	
	@Override
	public boolean isRunning() {
		System.out.println("-- isRunning " + isRunning + " --");
		return isRunning;
	}
    
	@Override
	public void start() {
		isRunning = true;
		System.out.println("-- start --");
	}
	
	@Override
	public void stop(Runnable stopCallback) {
		System.out.println("-- stop runnable --");
		stopCallback.run();
		isRunning = false;
	}
    
	@Override
	public void stop() {
		System.out.println("-- stop --");
	}
}
详细信息请参阅: http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-factory-lifecycle-processor


END...... 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值