对于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......
分享到:
相关推荐
Spring Bean创建初始化流程
本篇文章主要介绍了Spring 中如何控制2个bean中的初始化顺序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
3、通过spring的xml bean配置或bean注解指定初始化方法,如下面实例的initMethod方法通过@bean注解指定。 销毁的时候实现的方法 1、通过java提供的@PreDestroy注释; 2、通过实现spring提供的DisposableBean接口,并...
初始化后可访问Spring管理的Bean
它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中<bean/> 的形式定义。Spring 框架定义的beans都是单件beans。在bean tag中有个属性”singleton”,如果它被赋为...
下面小编就为大家带来一篇浅谈spring容器中bean的初始化。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
spring的初始化,可以让初学者了解soring的开发过程,让开发轻松进入开发大门。
Spring 源码分析(Bean的初始化) 前言 本篇文章是个人第一次看spring源码并总结,同时也参考了下面这篇博客。基本也是按照他的思路来理解的。这也算是第一版个人简易理解。也算是窥见spring的冰山一角,之后也会...
NULL 博文链接:https://bijian1013.iteye.com/blog/2374256
主要介绍了Spring Bean的初始化和销毁,结合实例形式详细分析了Spring Bean的初始化和销毁相关配置、使用方法及操作注意事项,需要的朋友可以参考下
你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。 面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务...
Spring IOC容器可以管理Bean的生命周期,允许在Bean生命周期的特定点执行定制的任务。 Spring IOC容器对Bean的生命周期...在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法。
Spring bean 一般通过配置文件和注解进行加载,如果要实现jar或class...测试示例中是spring boot 的部分代码,动态加载的内容为接口实现类,且初始化时加载本地的实现类,动态加载后改为非程序加载目录中的jar实现类。
Bean的初始化和销毁 Java配置方式 注解方式 Profile @Profile 通过设定jvm的spring.profiles.active参数 web项目设置在Servlet的context parameter中 事件Application Event 自定义事件,...
3.3.5. 延迟初始化bean 3.3.6. 自动装配(autowire)协作者 3.3.6.1. 设置Bean使自动装配失效 3.3.7. 依赖检查 3.3.8. 方法注入 3.3.8.1. Lookup方法注入 3.3.8.2. 自定义方法的替代方案 3.4. bean的作用域 3.4.1. ...
Spring源码学习六:bean初始化1
springBean加载过程源码解析文档,附有代码类名和行数
对于spring的ioc的简单通过xml配置bean完成初始化工作的实现。
.initialCacheNames(cacheNames) /* 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置 */ .withInitialCacheConfigurations(configMap).build(); return cacheManager; } 框架中...
Bean的之前初始化 19 Bean的准备就绪(Ready)状态 21 Bean的销毁 21 ApplicationContext 21 Spring的AOP框架 21 Spring的数据层访问 22 Spring的声明式事务 22 Spring对其它企业应用支持 22 注:后面的...