对于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的创建和初始化是IoC(Inversion of Control)容器的核心功能,这一过程涉及到多个步骤。以下是对Spring Bean创建初始化流程的详细解释: 1. **初始化ApplicationContext**: 开始时,通过`...
Spring 中控制 2 个 bean 的初始化顺序 在 Spring 框架中,控制多个 bean 的初始化顺序是一个常见的问题。本篇文章将详细介绍如何控制 2 个 bean 的初始化顺序,提供了多种实现方式,并分析了每种方式的优缺。 ...
例如,`<bean>`元素新增了`lazy-init`属性,可以指定bean是否延迟初始化,这有助于优化应用启动性能。`<beans>`元素添加了`default-lazy-init`属性,可以设置整个配置文件中所有bean的默认延迟初始化行为。此外,`...
`spring-context-4.2.xsd`包含了一系列元素,如`beans`、`bean`、`import`、`alias`、`bean-definition`等,这些都是Spring配置中的关键组成部分。例如,`<beans>`元素是所有配置的根元素,`<bean>`元素用于定义一个...
`BeanPostProcessor`接口允许自定义初始化和销毁Bean的逻辑。而`org.springframework.aop.framework.ProxyFactoryBean`则实现了AOP代理,通过动态代理机制,使得可以在不修改原始代码的情况下,添加新的行为。 此外...
本文将深入探讨如何在Spring容器初始化Bean和销毁Bean前后执行自定义的操作,以便于进行日志记录、资源清理等任务。 首先,我们需要了解Spring中Bean的生命周期。Bean的生命周期大致分为以下阶段: 1. 实例化:...
`spring-context`提供了应用程序上下文,负责管理和初始化bean;`spring-core`包含Spring的基本功能,如依赖注入;`spring-web`支持Web应用的开发,包括Servlet监听器和MVC架构;`spring-beans`处理bean的定义和实例...
工厂Bean允许开发者在对象实例化时进行更复杂的控制,比如引入特定的初始化过程、依赖注入或者资源管理。这篇博文将深入探讨工厂Bean的工作原理和使用场景。 首先,让我们理解什么是Bean。在Spring中,Bean是IoC...
在本项目中,Spring作为容器,管理着所有Bean的生命周期,通过XML配置文件或Java配置类来定义Bean的创建、初始化、销毁等过程。同时,Spring MVC作为其Web层组件,处理HTTP请求,实现业务逻辑和视图的解耦。 二、...
1. `<jdbc:initialize-database>`:用于自动初始化数据库,例如创建表、填充数据等,常在测试环境中使用。 2. `<jdbc:embedded-database>`:创建一个内存中的数据库,通常用于单元测试,如HSQLDB或Derby。 3. `<bean...
`@Sql`注解可以用来在测试前后执行SQL脚本,用于初始化或清理数据库状态,确保测试的隔离性。同时,`@Transactional`注解可以开启事务,测试结束后自动回滚,避免对数据库造成影响。 5. **测试报告:** Spring ...
通过Struts 2-Spring 插件,我们可以将Struts 2 的Action 对象交给Spring 来管理,Spring 负责初始化、配置和销毁这些对象。这样,Action 类不再需要自己去创建依赖的对象,而是通过构造函数或setter 方法接收Spring...
这篇“Spring学习笔记(2)----实例化Bean的三种方式”着重讲解了如何在Spring应用上下文中初始化Bean。以下是这三种方式的详细说明: 1. **XML配置方式** 在早期的Spring版本中,XML配置是最常见的实例化Bean的...
当Spring容器创建并初始化Bean时,会寻找带有@PostConstruct注解的方法并执行。 2. **InitializingBean接口** 如果一个Bean实现了Spring的InitializingBean接口,那么它必须重写`afterPropertiesSet()`方法。此...
2. **配置集成**:在Spring的配置文件中,需要添加MyBatis-Spring的相关配置,包括SqlSessionFactory和MapperScannerConfigurer,以便让Spring知道如何初始化和管理MyBatis的相关组件。 3. **Mapper接口**:创建...
在bean初始化时,`BeanFactory`会根据`BeanDefinition`中的依赖关系,自动将其他bean注入到当前bean的属性中。这种过程称为属性设置,可以通过setter方法、构造函数或者字段注入实现。源码中的`...
- **Lazy Initialization**:通过lazy-init属性,可以控制Bean是否延迟初始化,提高系统启动效率。 - **Auto-wiring**:自动装配功能,可以根据类型或名称自动查找并注入依赖。 在实际开发中,理解Spring-3.0.xsd...
一旦XML配置加载到Spring容器中,容器将根据配置创建Bean实例,并按照定义进行初始化、依赖注入,最后完成Bean的生命周期管理。 10. **实践操作**: 在实际开发中,我们可以使用Eclipse的Spring插件来简化Bean...
2. **生命周期管理**:Spring容器负责管理对象的生命周期,包括初始化、销毁等,开发者可以专注于业务逻辑,而不必关心对象的创建和销毁过程。 3. **AOP支持**:Spring的AOP功能可以在不修改原有代码的情况下,为...
默认情况下,`lazy-init`的值为`default`或`false`,意味着容器启动时就会初始化Bean。 Bean的初始化过程包括以下几个步骤: 1. **装载Bean定义**:Spring容器读取XML配置文件,解析Bean的定义,包括其类型、依赖...