《Spring攻略》 第1章 Spring简介 - IoC基础

本文介绍了Spring IoC容器的基本概念、配置方法及高级特性,包括Bean实例化、依赖注入、自动装配、组件扫描等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1实例化SpringIoC容器

问题:
你必须实例化Spring IoC容器,读取配置来创建bean实例。然后,你可以从Spring IoC容器中得到可用的bean实例。


解决方案:
Spring提供了两种IoC容器实现类型。基本的一种称为Bean工厂(Bean Factory)。另一种称为应用程序上下文(Application Context),这是对bean工厂的一种兼容扩展。
这两种IoC容器类型和Bean配置文件相同。
ApplicationContext接口是用于保持兼容性的BeanFactory的子接口。

<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<spring.version>3.1.1.RELEASE</spring.version>
</properties>

<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-aop</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context-support</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-beans</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>${spring.version}</version>
	</dependency>

	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>3.8.1</version>
		<scope>test</scope>
	</dependency>
</dependencies>

工作原理:
实例化应用程序上下文-
各种实现加载文件方式ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、XmlWebApplicationContext等


从IoC容器中得到bean-
为了从bean工厂或者应用程序上下文中得到已声明的bean,你只需要调用getBean()方法并且传递唯一的bean名称,返回Object。


2配置Spring IoC容器中的bean

问题:
Spring提供了一个强大的IoC容器来管理组成应用的Bean。为了使用,你必须配置。


解决方案:
你可以通过XML配置文件、属性文件等方式进行配置。
在简单应用中你可以使用单个配置文件,但是在庞大的系统中一般都会分模块存在多个配置文件或者按照架构层次进行分割。


工作原理:


helloworld:


1、两种基本的简单IoC

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

	/*public Love() {
		super();
	}*/

	public Love(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String toString() {
		return "Love [name=" + name + ", age=" + age + "]";
	}

}

	<bean id="loveSet" class="com.partner4java.Love">
		<property name="name" value="gaofumei"></property>
		<property name="age" value="16"></property>
	</bean>
	
	<bean id="loveConstructor" class="com.partner4java.Love">
		<constructor-arg name="name" value="gaofumei"/>
		<constructor-arg name="age" value="18"/>
	</bean>

/**
 * 对两种注入类型进行测试,如果是方法注入,Love类中如果包含有构造器,还必须包含无参数的构造器<br/>
 * (这个错误不是在第一次获取bean的时候报出来的,是在初始化之后报的,因为单例类型的bean会在初始化时期完成,你可以加上 scope="prototype"证明这一点)
 * 
 * @author partner4java
 * 
 */
public class LoveTest {
	private ApplicationContext applicationContext;

	@Before
	public void setUp() throws Exception {
		applicationContext = new ClassPathXmlApplicationContext(
				"/spring/beans1.xml");
	}

	@Test
	public void testSet() {
		Love love = (Love) applicationContext.getBean("loveSet");
		System.out.println(love);
	}

	@Test
	public void testConstructor() {
		Love love = (Love) applicationContext.getBean("loveConstructor");
		System.out.println(love);
	}
}

spring2.0之后又新增了缩写的配置方式:

xmlns:p="http://www.springframework.org/schema/p"

<bean id="loveShort" class="com.partner4java.Love" p:name="gaofumei" p:age="20"/>

@Test
public void testShort() {
	Love love = (Love) applicationContext.getBean("loveShort");
	System.out.println(love);
}
比着前面,我们就更加简洁了



2、为Bean配置集合
就是包括基本的List、Set、Map等,基本用法没有什么好说的
但是,当你使用继承的时候,可以使用<list merge="true">来在子类中声明合并父类,但是会放在父类的序列之后。

public class Wife {
	private List<String> wifeNames;

	public void setWifeNames(List<String> wifeNames) {
		this.wifeNames = wifeNames;
	}

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

}

<bean id="wife" class="com.partner4java.Wife">
	<property name="wifeNames">
		<list>
			<value>gaofumei</value>
			<value>xiaoneinv</value>
		</list>
	</property>
</bean>

public class WifeTest {
	private ApplicationContext applicationContext;

	@Before
	public void setUp() throws Exception {
		applicationContext = new ClassPathXmlApplicationContext(
				"/spring/beans2.xml");
	}

	@Test
	public void testSetWifeNames() {
		Wife wife = (Wife) applicationContext.getBean("wife");
		System.out.println(wife);
	}

}


3调用构造程序创建bean

问题:
你想要调用构造程序在Spring IoC容器中创建 一个bean,这是创建Bean最常见和直接的方法。


解决方案:
通常,当你为一个Bean指定class属性,就将要求Spring IoC容器调用构造程序创建Bean实例。


工作原理:

执行过程
FileSystemXmlApplicationContext
	↓
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
刷新入口
	↓
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
实例化所有的(non-lazy-init)单例 
	↓
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
Instantiate all remaining (non-lazy-init) singletons,进行遍历
	↓
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
调用获取动作doGetBean
	↓
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
获取共享实例sharedInstance
	↓
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
创建了一个内部的ObjectFactory,定义了一个内部getObject方法,然后
	↓
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
调用父类实现的createBean方法
	↓
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
判断一些条件后调用执行方法doCreateBean
	↓
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
大部分实例动作的包装类(包括485的createBeanInstance--构建实例、)
	↓
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118)
填充数据(下面就是判断、遍历填充数据)
	↓
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360)
	↓
org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:153)
	↓
org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:353)
	↓
org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:194)


AbstractAutowireCapableBeanFactory的:createBeanInstance
方法最后面
// Need to determine the constructor...
Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
		mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
		mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
	return autowireConstructor(beanName, mbd, ctors, args);
}

// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);

这里就是为什么如果不不含构造器的IoC,还没有默认无参构造器的时候,会报错Instantiation of bean failed的原因。



4解决构造程序歧义

问题:
当你为Bean指定一个或者多个构造程序参数时,Spring将视图在Bean类中查找对应的构造程序,并且传递用于Bean实例化的参数。


解决方案:
你可以为<constructor-arg>元素指定type和index属性,帮助Spring查找预期的构造程序。


工作原理:
从下面的地方开始说

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
	↓
createBeanInstance方法中
		// Need to determine the constructor...
		Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			return autowireConstructor(beanName, mbd, ctors, args);
		}
判断了,如果有构造IoC,那么进行...
	↓			
获取BeanWrapper
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
	↓
autowireConstructor进行了具体的index和type匹配


5指定Bean引用

问题:
组成应用程序的Bean往往需要互相协作完成应用功能。为了Bean之间的互相访问,你必须在Bean配置文件中指定Bean引用。

解决方案:
在Bean配置文件中,你可以用<ref>元素为Bean属性或者构造程序参数指定Bean引用。
只需要用<value>元素指定一个值。

工作原理:
<bean id="user" class="com.partner4java.ref.User">
	<property name="username" value="gaolumei"></property>
	<property name="age" value="18"></property>
</bean>

<bean id="buy" class="com.partner4java.ref.Buy">
	<property name="user" ref="user"></property>
</bean>

public class RefTest {
	private ApplicationContext applicationContext;

	@Before
	public void setUp() throws Exception {
		applicationContext = new ClassPathXmlApplicationContext(
				"/spring/beans3.xml");
	}	
	
	@Test
	public void testBuy(){
		System.out.println(applicationContext.getBean("buy"));
	}
}


AbstractBeanFactory.doGetBean调用获取bean 
--> 
AbstractAutowireCapableBeanFactory.applyPropertyValues加载参数(IoC操作)
-->
BeanDefinitionValueResolver.resolveReference(获取ref的对应的bean)


6为集合元素指定数据类型

问题:
默认情况下,Spring将集合中所有元素作为字符串对待。
如果你不打算将集合元素作为字符串使用,就必须为他们指定数据类型。


解决方案:
可以使用<value>的type指定,也可以在集合标记中指定value-type


工作原理:

public class Cache {
	private List<String> wifes;

	public List<String> getWifes() {
		return wifes;
	}

	public void setWifes(List<String> wifes) {
		this.wifes = wifes;
	}

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

}

<bean id="cache" class="com.partner4java.type.Cache">
	<property name="wifes">
		<list value-type="java.lang.String">
			<value>gaofumei</value>
			<value>dachangtui</value>
		</list>
	</property>
</bean>



具体的封装从BeanDefinitionValueResolver开始说:
然后又借助TypeConverter类型转换器
-->
借助BeanWrapperImpl来获取获取BeanWrapper
-->
借助TypeConverterDelegate进行帮助类型转换
-->
TypeConverterDelegate调用doConvertTextValue
-->
利用包org.springframework.beans.propertyeditors里的各种类型转换辅助工具类进行数据复制和对象获取。
当然具体类型转换还需要靠如NumberUtils


7使用Spring的FactoryBean创建bean

问题:
你可能希望用Spring的工厂Bean在Spring IoC容器中创建Bean。
工厂Bean(Factory Bean)是作为创建IoC容器中其他Bean的工厂的一个FactoryBean。概念上,工厂Bean与工厂方法非常类似,但是他是Bean构造期间可以Spring IoC容器识别为Spring专用Bean。


解决方案:
工厂Bean的要求是实现FactoryBean接口。为了方便,提供了抽象模板类AbstractFactoryBean供你扩展。
工厂Bean主要用于实现框架机制。如:
·在JNDI中查找对象(例如一个数据源)时,你可以使用JndiObjectFactoryBean。
·使用经典Spring AOP为一个Bean创建代理时,可以使用ProxyFactoryBean。
·在IoC容器中创建一个Hibernate会话工厂时,可以使用LocalSessionFactoryBean。


工作原理:
尽管你很少有必要编写自定义的工厂Bean,但是会发现通过一个实例来理解其内部机制很有帮助。
通过扩展AbstractFactoryBean类,你的工厂bean能够重载createInstance()方法以创建目标Bean实例。
此外,你必须getObjectType()方法中返回目标Bean的类型,是自动装配(Auto-wiring)功能正常工作。
名称之前添加&,可以得到工厂Bean的实例。

public class DiscountFactoryBean extends AbstractFactoryBean<User> {
	private User user;

	public void setUser(User user) {
		this.user = user;
	}

	@Override
	public Class<?> getObjectType() {
		return user.getClass();
	}

	@Override
	protected User createInstance() throws Exception {
		return user;
	}

}
<bean id="xiaomei" class="com.partner4java.DiscountFactoryBean">
	<property name="user">
		<bean class="com.partner4java.ref.User">
			<property value="xiaomeimei" name="username"></property>
			<property value="18" name="age"></property>
		</bean>
	</property>
</bean>

@Test
public void testFactoryBean() throws Exception {
	User user = (User) applicationContext
			.getBean("xiaomei");
	System.out.println(user);
}	

@Test
public void testNewFactoryBean() throws Exception {
	DiscountFactoryBean discountFactoryBean = new DiscountFactoryBean();
	User user = new User();
	user.setUsername("gaofumei");
	user.setAge(16);
	discountFactoryBean.setUser(user);
	System.out.println(discountFactoryBean.createInstance());
}

@Test
public void testGetFactoryBean() throws Exception {
	DiscountFactoryBean discountFactoryBean = (DiscountFactoryBean) applicationContext.getBean("&xiaomei");
	System.out.println(discountFactoryBean.createInstance());
}


8使用工厂Bean和Utility Schema定义集合

问题:
使用基本集合标记定义集合时,你不能指定集合的实体类,例如LinkedList、TreeSet或TreeMap,而且,你不能通过将集合定义为可供其他Bean引用的单独Bean在不同的Bean中共享集合。


解决方案:
两种方式
1、使用对应的集合工厂Bean,如ListFactoryBean、SetFactoryBean和MapFactoryBean。
2、引入util schema中使用集合标记,如<util:list>、<util:set>和<util:map>。


工作原理:

public class SetBean {
	private Set<String> name;

	public Set<String> getName() {
		return name;
	}

	public void setName(Set<String> name) {
		this.name = name;
	}

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

<bean id="names1" class="org.springframework.beans.factory.config.SetFactoryBean">
	<property name="sourceSet">
		<set>
			<value>gaofumei</value>
			<value>小甜甜</value>
		</set>
	</property>
</bean>

<bean id="setBean1" class="com.partner4java.SetBean">
	<property name="name" ref="names1"></property>
</bean>

<util:set id="names2">
	<value>清纯</value>
	<value>小甜甜</value>
</util:set>

<bean id="setBean2" class="com.partner4java.SetBean">
	<property name="name" ref="names2"></property>
</bean>

@Test
public void testGet1() throws Exception {
	System.out.println(applicationContext.getBean("setBean1"));
}

@Test
public void testGet2() throws Exception {
	System.out.println(applicationContext.getBean("setBean2"));
}



9用依赖检查属性

问题:
在大规模的应用中,IoC容器中可能声明了几百个甚至几千上万个Bean,这些Bean之间的依赖往往非常复杂。
设置方法注入的不足之一是无法确定一个属性将会被注入。
检查所有必要的属性是否已经设置是非常困难的。




解决方案:
dependency-check --
none* 不执行任何依赖检查,任何属性都可以保持未设置状态
simple 如果任何简单类型(原始和集合类型)的属性未设置,将抛出UnsatisfiedDependencyException异常
objects 如果任何对象类型属性没有设置,将抛出UnsatisfiedDependencyException异常
all 如果任何类型的属性为设置,将抛出UnsatisfiedDependencyException异常


工作原理:
不过在新的版本中已经废弃


10用@Required注解检查属性

问题:
Spring的依赖检查功能仅能检查某些类型的所有属性。他的灵活性不够,不能仅检查特定的属性。

解决方案:
RequiredAnnotationBeanPostProcessor是一个Spring bean后处理器,检查带有@Required注解的所有bean属性是否设置。
bean后处理器是一类特殊的Spring bean,能够在每个Bean初始化之前执行附加的工作。
为了启用这个Bean后处理器进行属性检查,必须在Spring IoC容器中注册他。

工作原理:
Caused by: org.springframework.beans.factory.BeanInitializationException: Property 'username' is required for bean 'user'

public class User {
	private String username;
	private int age;

	public String getUsername() {
		return username;
	}

	@Required
	public void setUsername(String username) {
		this.username = username;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [username=" + username + ", age=" + age + "]";
	}

}

<context:annotation-config />
<bean id="user" class="com.partner4java.ref.User">
	<property value="18" name="age"></property>
</bean>

还可以自定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Mandatory {

}

public class User {
	private String username;
	private int age;

	public String getUsername() {
		return username;
	}

	@Mandatory
	public void setUsername(String username) {
		this.username = username;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [username=" + username + ", age=" + age + "]";
	}

}

<context:annotation-config/>

<!-- 不需要额外再通知谁 -->
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor">
	<property name="requiredAnnotationType">
		<value>com.partner4java.Mandatory</value>
	</property>
</bean>

<bean id="user" class="com.partner4java.ref.User">
	<property value="18" name="age"></property>
</bean>


11用XML配置自动装配Bean

问题:
当一个Bean需要访问另一个Bean时,你可以显示指定引用装配他。但是,如果你的容器能够自动装配bean,就可以免去手工手工配置装配的麻烦。


解决方案:
autowire属性--
no* 不执行自动装配。你必须显示的装配依赖
byName 对于每个Bean属性,装配一个同名的bean
byType 对于每个Beam属性,装配类型与之兼容的Bean。如果超过一个,将抛出UnsatisfiedDependencyException异常。
Constructor 对于每个构造程序参数,首先寻找与参数兼容的Bean。然后,选择具有最多参数的构造程序。对于存在歧义的情况,将抛出UnsatisfiedDependencyException异常。
autoetect 如果找到一个没有参数的默认构造程序,依赖讲按照类型自动装配。否则,将由构造程序自动装配。


(不建议用自动装配)


工作原理:

public class User {
	private String username;
	private int age;

	public String getUsername() {
		return username;
	}

	@Mandatory
	public void setUsername(String username) {
		this.username = username;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [username=" + username + ", age=" + age + "]";
	}

}

public class Teacher {
	private User user;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

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

<bean id="user" class="com.partner4java.ref.User">
	<property name="username" value="xiaomeimei"></property>
	<property value="18" name="age"/>
</bean>

<bean id="teacher" class="com.partner4java.Teacher" autowire="byName">
</bean>

@Test
public void testCheck(){
	System.out.println(applicationContext.getBean("teacher"));
}

后台打印:
Teacher [user=User [username=xiaomeimei, age=18]]


12用@Autowired和@Resource自动装配Bean

问题:
在Bean配置文件中设置autowire属性进行的自动装配将装配一个Bean的所有属性。这样的灵活性不足以紧紧装配特定的属性。
而且,你只能通过类型或者名称自动装配Bean。
如果这两种策略都不能满足你的需求,就必须明确的装配Bean。


解决方案:
你可以通过@Autowired或者@Resource注解一个设置方法、构造程序、字段甚至任意方法自动装配特定的属性。
这意味着你除了设置autowire属性之外,还有一个能够满足需求的选择。


工作原理:
<context:annotation-config />


@Autowired、@Qualifier("mainCatalog")、@Resource(name="myMovieFinder")



13继承Bean配置

问题:
在Spring IoC容器中配置Bean时,你可能拥有超过一个共享某些公用配置的Bean,比如属性和<bean>元素中的属性。你常常必须为多个Bean重复这些配置。

解决方案:
只作为模板而不能检索,必须将abstract设置为true,要求spring不实例化这个bean。
并不是所有在父<bean>元素中定义的属性都将被继承,例如,autowire和dependency-check属性不会从父bean中继承。

工作原理:
public abstract class Water {
	private int weight;
	private int depth;

	public int getWeight() {
		return weight;
	}

	public void setWeight(int weight) {
		this.weight = weight;
	}

	public int getDepth() {
		return depth;
	}

	public void setDepth(int depth) {
		this.depth = depth;
	}

	@Override
	public String toString() {
		return "Water [weight=" + weight + ", depth=" + depth + "]";
	}

}

public class Coke extends Water {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Coke [name=" + name + ", toString()=" + super.toString() + "]";
	}

}

public class Energy extends Water {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Energy [name=" + name + ", toString()=" + super.toString() + "]";
	}

}


<!-- 第一种:常用的模板模式,抽象接口里面放了基本的资源,子类放了具体的资源 -->
<bean id="water" class="com.partner4java.parent.Water" abstract="true">
	<property name="weight" value="100"></property>
	<property name="depth" value="10"></property>
</bean>

<bean id="coke" class="com.partner4java.parent.Coke" parent="water">
	<property name="name" value="coke"></property>
</bean>

<bean id="energy" class="com.partner4java.parent.Energy" parent="water">
	<property name="name" value="Energy"></property>
</bean>
<!-- 子bean没有指定class也可以 -->
<bean id="mineralWater" parent="energy">
	<property name="weight" value="1000"></property>
</bean>

<!-- 第二种:只定义一个抽象资源,然后让bean去继承 -->

<bean id="noWater" abstract="true">
	<property name="weight" value="100"></property>
	<property name="depth" value="10"></property>
</bean>

<bean id="noEnergy" class="com.partner4java.parent.Energy" parent="noWater">
	<property name="name" value="Energy"></property>
</bean>

public class ParentTest {
	private ApplicationContext applicationContext;

	@Before
	public void setUp() throws Exception {
		applicationContext = new ClassPathXmlApplicationContext(
				"/spring/beans13_parent.xml");
	}
	
	@Test
	public void testCoke(){
		System.out.println(applicationContext.getBean("coke"));
	}
	
	@Test
	public void testEnergy(){
		System.out.println(applicationContext.getBean("energy"));
	}
	
	@Test
	public void testMineralWater(){
		System.out.println(applicationContext.getBean("mineralWater"));
	}
	
	@Test
	public void testNoEnergy(){
		System.out.println(applicationContext.getBean("noEnergy"));
	}
}



14从Classpath中扫描组件

问题:
为了便于Spring IoC容器对组件的管理,你需要在Bean配置中逐个声明他们。
但是,如果Spring能够自动地检测你的组件而不需要手工配置,将大大节省你的工作量。

解决方案:
Spring提供了一个强大的功能--组件扫描@Component.
@Repository\@Service\@Controller:持久层、服务层和表现层。

工作原理:
<?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"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-3.0.xsd">
        
	<context:annotation-config />
	<context:component-scan base-package="com.partner4java" />
</beans>   

public interface UserDao {
	public void save(Integer id);
	public void delete(Integer id);
	public boolean get(Integer id);
}

@Scope("singleton")
@Repository
public class UserDaoImpl implements UserDao {
	private List<Integer> users = new LinkedList<Integer>();
	@Override
	public void save(Integer id) {
		users.add(id);
	}

	@Override
	public void delete(Integer id) {
		users.remove(id);
	}

	@Override
	public boolean get(Integer id) {
		return users.contains(id);
	}

}

public interface UserService {
	public void save(Integer id);
	public void delete(Integer id);
	public boolean get(Integer id);
}

@Service
public class UserServiceImpl implements UserService {
	private UserDao userDao;
	
	@Autowired
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public void save(Integer id) {
		userDao.save(id);
	}

	@Override
	public void delete(Integer id) {
		userDao.delete(id);
	}

	@Override
	public boolean get(Integer id) {
		return userDao.get(id);
	}

}

public class ScanTest {
	private ApplicationContext applicationContext;

	@Before
	public void setUp() throws Exception {
		applicationContext = new ClassPathXmlApplicationContext(
				"/spring/beans14_scan.xml");
	}
	
	@Test
	public void testAll(){
		UserServiceImpl  userServiceImpl = (UserServiceImpl) applicationContext.getBean("userServiceImpl");
		userServiceImpl.save(new Integer(1));
		userServiceImpl.save(new Integer(2));
		userServiceImpl.delete(new Integer(2));
		System.out.println(userServiceImpl.get(1));
		System.out.println(userServiceImpl.get(2));
	}
	
}



因为上传大小的限制,分为两部分上传,这是第二部分,第一部分会在评论中给出链接 绝对是spring攻略中文版第二版 Spring专家力作 理论与实践完美结合 问题描述→解决方案→实现方法 第一部分 核心概念  第1 控制反转和容器    1.1 使用容器管理组件     1.1.1 问题描述     1.1.2 解决方案     1.1.3 实现方法    1.2 使用服务定位器降低查找组件的复杂性     1.2.1 问题描述     1.2.2 解决方案     1.2.3 实现方法    1.3 应用控制反转和依赖注入     1.3.1 问题描述     1.3.2 解决方案     1.3.3 实现方法    1.4 理解不同类型的依赖注入     1.4.1 问题描述     1.4.2 解决方案     1.4.3 实现方法    1.5 使用配置文件配置容器      1.5.1 问题描述     1.5.2 解决方案     1.5.3 实现方法    1.6 小结   第2 Spring简介    2.1 Spring Framework     2.1.1 Spring的模块介绍     2.1.2 Spring的发布版本     2.1.3 Spring的项目    2.2 安装Spring Framework     2.2.1 问题描述     2.2.2 解决方案     2.2.3 实现方法    2.3 建立Spring项目     2.3.1 问题描述     2.3.2 解决方案     2.3.3 实现方法    2.4 安装Spring IDE     2.4.1 问题描述     2.4.2 解决方案     2.4.3 实现方法    2.5 使用Spring IDE的Bean-supporting特性     2.5.1 问题描述     2.5.2 解决方案     2.5.3 实现方法    2.6 小结   第3 Spring中的Bean配置    3.1 在Spring IoC容器里配置Bean     3.1.1 问题描述     3.1.2 解决方案     3.1.3 实现方法   3.2 实例化Spring IoC容器      3.2.1 问题描述     3.2.2 解决方案     3.2.3 实现方法    3.3 解决构造器歧义     3.3.1 问题描述     3.3.2 解决方案     3.3.3 实现方法   第4 高级Spring IoC容器   第5 动态代理和经典的Spring AOP   第6 Spring 2.x AOP和AspectJ支持  第二部分 基础主题  第7 Spring对JDBC的支持   第8 Spring中的事务管理   第9 Spring对ORM的支持   第10 Spring MVC框架   第11 整合Spring与其他Web框架   第12 Spring对测试的支持  第三部分 高级主题  第13 Spring Security框架   第14 Spring Portlet MVC框架   第15 Spring Web Flow   第16 Spring远程服务和Web服务   第17 Spring对EJB和JMS的支持   第18 Spring对JMX、电子邮件和调度的支持   第19 Spring中的脚本编程 
随着Spring框架最新版本——3.0版的发布,Spring平台已经发展成熟,成为JavaJava虚拟机、Groovy、NET或者Action-Script开发人员最强大、最具革命性的解决方案之一。 《Spring攻略(第2版)》是Spring平台的深入指南,它引导你进入Spring 3及其辅助框架的最新技术。《Spring攻略(第2版)》不仅为你全面而又深入地讲解各种概念,并且在每一中都配备了一系列详细的代码示例,以帮助读者在实际的工作中迅速应用于实战。 SpringSource为核心框架添加了许多部件。这些部件不仅简化了Java EE之上的API,并且为Java EE所忽略的问题提供了第一流的完整解决方案。构建于Spring IoC容器组件模型之上的这些Spring3部件提供了集成、批处理、OSGi、Ajax和Flex集成、状态式的Web应用、REST风格Web服务、富客户端用户界面、Google AppEngine开发、基于云的部署、消息、数据访问、Web服务等多种功能。而且,Spring能很好地与其他辅助框架(包括业务过程管理、群集缓冲以及网格计算)进行协作。 你在寻求和Ruby on Rails一样的一体化架构吗?那么你会被Grails等Spring替代方案所深深吸引,对于Groovy开发人员来说,Grails具有难以置信的能力和生产率。如果你是寻求快速、轻量级的应用构建方法的Java开发人员,你会喜欢上Spring Roo,它能让你快速地通过应用的原型阶段,进入维护阶段,形成清晰的、面向最佳实践的代码。 以上所有这些主题,在这本以丰富代码为基础攻略中都能找到。我们希望你能够享受Spring平台的学习和使用。 Gary Mak,Josh Long和Daniel Rubio。 作者简介 作者:(美国)麦克(Gary Mak) (美国)隆(Josh Long) (美国)卢比奥(Daniel Rubio) 译者:陈宗恒 姚军 蒋亮 麦克,Gary Mak,Meta-Archit软件技术有限公司的创立者及首席顾问。 隆,Josh Long,SpringSource的Spring开发倡导人。 卢比奥,Daniel Rubio,超过10年的企业级和Web开发经验顾问。
本书共分为两卷。 第1 Spring简介 1 1.1 实例化Spring IoC容器 1 1.1.1 问题 1 1.1.2 解决方案 1 1.1.3 工作原理 3 1.2 配置Spring IoC容器中的Bean 4 1.2.1 问题 4 1.2.2 解决方案 4 1.2.3 工作原理 4 1.3 调用构造程序创建Bean 14 1.3.1 问题 14 1.3.2 解决方案 14 1.3.3 工作原理 14 1.4 解决构造程序歧义 17 1.4.1 问题 17 1.4.2 解决方案 17 1.4.3 工作原理 17 1.5 指定Bean引用 20 1.5.1 问题 20 1.5.2 解决方案 20 1.5.3 工作原理 20 1.6 为集合元素指定数据类型 24 1.6.1 问题 24 1.6.2 解决方案 24 1.6.3 工作原理 24 1.7 使用Spring的FactoryBean创建Bean 27 1.7.1 问题 27 1.7.2 解决方案 27 1.7.3 工作原理 27 1.8 使用工厂Bean和Utility Schema定义集合 29 1.8.1 问题 29 1.8.2 解决方案 29 1.8.3 工作原理 29 1.9 用依赖检查属性 31 1.9.1 问题 31 1.9.2 解决方案 32 1.9.3 工作原理 32 1.10 用@Required注解检查属性 34 1.10.1 问题 34 1.10.2 解决方案 34 1.10.3 工作原理 34 1.11 用XML配置自动装配Bean 36 1.11.1 问题 36 1.11.2 解决方案 36 1.11.3 工作原理 37 1.12 用@Autowired和@Resource自动装配Bean 41 1.12.1 问题 41 1.12.2 解决方案 41 1.12.3 工作原理 41 1.13 继承Bean配置 47 1.13.1 问题 47 1.13.2 解决方案 47 1.13.3 工作原理 48 1.14 从Classpath中扫描组件 50 1.14.1 问题 50 1.14.2 解决方案 51 1.14.3 工作原理 51 1.15 小结 56 第2 高级Spring IoC容器 57 2.1 调用静态工厂方法创建Bean 57 2.1.1 问题 57 2.1.2 解决方案 57 2.1.3 工作原理 57 2.2 调用一个实例工厂方法创建Bean 58 2.2.1 问题 58 2.2.2 解决方案 59 2.2.3 工作原理 59 2.3 从静态字段中声明Bean 60 2.3.1 问题 60 2.3.2 解决方案 60 2.3.3 工作原理 61 2.4 从对象属性中声明Bean 62 2.4.1 问题 62 2.4.2 解决方案 62 2.4.3 工作原理 62 2.5 使用Spring表达式语言 64 2.5.1 问题 64 2.5.2 解决方案 64 2.5.3 工作原理 65 2.6 设置Bean作用域 69 2.6.1 问题 69 2.6.2 解决方案 69 2.6.3 工作原理 70 2.7 自定义Bean初始化和析构 72 2.7.1 问题 72 2.7.2 解决方案 72 2.7.3 工作原理 72 2.8 用Java Config简化XML配置 77 2.8.1 问题 77 2.8.2 解决方案 77 2.8.3 工作原理 77 2.9 使Bean感知容器 81 2.9.1 问题 81 2.9.2 解决方案 81 2.9.3 工作原理 82 2.10 加载外部资源 82 2.10.1 问题 82 2.10.2 解决方案 83 2.10.3 工作原理 83 2.11 创建Bean后处理器 85 2.11.1 问题 85 2.11.2 解决方案 85 2.11.3 工作原理 86 2.12 外部化Bean配置 89 2.12.1 问题 89 2.12.2 解决方案 89 2.12.3 工作原理 90 2.13 解析文本消息 91 2.13.1 问题 91 2.13.2 解决方案 91 2.13.3 工作原理 91 2.14 使用应用事件进行通信 93 2.14.1 问题 93 2.14.2 解决方案 93 2.14.3 工作原理 94 2.15 在Spring中注册属性编辑器 96 2.15.1 问题 96 2.15.2 解决方案 96 2.15.3 工作原理 97 2.16 创建自定义属性编辑器 99 2.16.1 问题 99 2.16.2 解决方案 100 2.16.3 工作原理 100 2.17 使用TaskExecutor实现并发性 101 2.17.1 问题 101 2.17.2 解决方案 101 2.17.3 工作原理 102 2.18 小结 110 第3 Spring AOP和AspectJ支持 112 3.1 启用Spring的AspectJ注解支持 113 3.1.1 问题 113 3.1.2 解决方案 113 3.1.3 工作原理 113 3.2 用AspectJ注解声明aspect 115 3.2.1 问题 115 3.2.2 解决方案 115 3.2.3 工作原理 116 3.3 访问连接点信息 121 3.3.1 问题 121 3.3.2 解决方案 122 3.3.3 工作原理 122 3.4 指定aspect优先级 123 3.4.1 问题 123 3.4.2 解决方案 123 3.4.3 工作原理 123 3.5 重用切入点定义 125 3.5.1 问题 125 3.5.2 解决方案 125 3.5.3 工作原理 125 3.6 编写AspectJ切入点表达式 127 3.6.1 问题 127 3.6.2 解决方案 127 3.6.3 工作原理 128 3.7 在你的Bean中引入行为 132 3.7.1 问题 132 3.7.2 解决方案 132 3.7.3 工作原理 132 3.8 为你的Bean引入状态 135 3.8.1 问题 135 3.8.2 解决方案 135 3.8.3 工作原理 135 3.9 用基于XML的配置声明aspect 137 3.9.1 问题 137 3.9.2 解决方案 137 3.9.3 工作原理 137 3.10 Spring中的AspectJ加载时织入aspect 140 3.10.1 问题 140 3.10.2 解决方案 141 3.10.3 工作原理 141 3.11 在Spring中配置AspectJ aspect 146 3.11.1 问题 146 3.11.2 解决方案 146 3.11.3 工作原理 146 3.12 将Spring Bean注入领域对象 147 3.12.1 问题 147 3.12.2 解决方案 147 3.12.3 工作原理 148 3.13 小结 151 第4 Spring中的脚本 152 4.1 用脚本语言实现Bean 152 4.1.1 问题 152 4.1.2 解决方案 153 4.1.3 工作原理 153 4.2 将Spring Bean注入脚本中 157 4.2.1 问题 157 4.2.2 解决方案 157 4.2.3 工作原理 157 4.3 从脚本中刷新Bean 160 4.3.1 问题 160 4.3.2 解决方案 160 4.3.3 工作原理 160 4.4 定义内联脚本源码 161 4.4.1 问题 161 4.4.2 解决方案 161 4.4.3 工作原理 161 4.5 小结 163 第5 Spring Security 164 5.1 加强URL访问安全 165 5.1.1 问题 165 5.1.2 解决方案 165 5.1.3 工作原理 166 5.2 登录到Web应用 175 5.2.1 问题 175 5.2.2 解决方案 175 5.2.3 工作原理 175 5.3 验证用户 179 5.3.1 问题 179 5.3.2 解决方案 180 5.3.3 工作原理 180 5.4 做出访问控制决策 190 5.4.1 问题 190 5.4.2 解决方案 190 5.4.3 工作原理 191 5.5 加强方法调用的安全 193 5.5.1 问题 193 5.5.2 解决方案 193 5.5.3 工作原理 194 5.6 处理视图中的安全性 196 5.6.1 问题 196 5.6.2 解决方案 196 5.6.3 工作原理 196 5.7 处理领域对象安全性 198 5.7.1 问题 198 5.7.2 解决方案 198 5.7.3 工作原理 199 5.8 小结 208 第6 将Spring与其他Web框架集成 209 6.1 在一般Web应用中访问Spring 209 6.1.1 问题 209 6.1.2 解决方案 210 6.1.3 工作原理 210 6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2 解决方案 215 6.2.3 工作原理 215 6.3 将Spring与Struts 1.x集成 220 6.3.1 问题 220 6.3.2 解决方案 220 6.3.3 工作原理 220 6.4 将Spring与JSF集成 226 6.4.1 问题 226 6.4.2 解决方案 226 6.4.3 工作原理 227 6.5 将Spring与DWR集成 232 6.5.1 问题 232 6.5.2 解决方案 232 6.5.3 工作原理 233 6.6 小结 236 第7 Spring Web Flow 238 7.1 用Spring Web Flow管理简单的UI流程 238 7.1.1 问题 238 7.1.2 解决方案 239 7.1.3 工作原理 239 7.2 用不同状态类型建立Web流程模型 246 7.2.1 问题 246 7.2.2 解决方案 246 7.2.3 工作原理 246 7.3 加强Web流程安全 257 7.3.1 问题 257 7.3.2 解决方案 258 7.3.3 工作原理 258 7.4 持续存储Web流程中的对象 260 7.4.1 问题 260 7.4.2 解决方案 260 7.4.3 工作原理 260 7.5 将Spring Web Flow与JSF集成 267 7.5.1 问题 267 7.5.2 解决方案 267 7.5.3 工作原理 267 7.6 使用RichFaces与Spring WebFlow协作 275 7.6.1 问题 275 7.6.2 解决方案 275 7.6.3 方法 275 7.7 小结 279 第8 Spring @MVC 280 8.1 用Spring MVC开发简单的Web应用 280 8.1.1 问题 280 8.1.2 解决方案 281 8.1.3 工作原理 283 8.2 用@RequestMapping映射请求 293 8.2.1 问题 293 8.2.2 解决方案 294 8.2.3 工作原理 294 8.3 用处理程序拦截器拦截请求 297 8.3.1 问题 297 8.3.2 解决方案 298 8.3.3 工作原理 298 8.4 解析用户区域 302 8.4.1 问题 302 8.4.2 解决方案 302 8.4.3 工作原理 302 8.5 外部化区分区域的文本信息 304 8.5.1 问题 304 8.5.2 解决方案 304 8.5.3 工作原理 305 8.6 按照名称解析视图 306 8.6.1 问题 306 8.6.2 解决方案 306 8.6.3 工作原理 306 8.7 视图和内容协商 309 8.7.1 问题 309 8.7.2 解决方案 309 8.7.3 工作原理 309 8.8 映射异常视图 312 8.8.1 问题 312 8.8.2 解决方案 312 8.8.3 工作原理 312 8.9 用@Value在控制器中赋值 314 8.9.1 问题 314 8.9.2 解决方案 314 8.9.3 工作原理 314 8.10 用控制器处理表单 316 8.10.1 问题 316 8.10.2 解决方案 316 8.10.3 工作原理 317 8.11 用向导表单控制器处理多页表单 331 8.11.1 问题 331 8.11.2 解决方案 331 8.11.3 工作原理 332 8.12 使用注解(JSR-303)的Bean校验 341 8.12.1 问题 341 8.12.2 解决方案 342 8.12.3 工作原理 342 8.13 创建Excel和PDF视图 344 8.13.1 问题 344 8.13.2 解决方案 345 8.13.3 工作原理 345 8.14 小结 351 第9 Spring REST 352 9.1 用Spring发布一个REST服务 352 9.1.1 问题 352 9.1.2 解决方案 353 9.1.3 工作原理 353 9.2 用Spring访问REST服务 358 9.2.1 问题 358 9.2.2 解决方案 358 9.2.3 工作原理 358 9.3 发布RSS和Atom信息源 362 9.3.1 问题 362 9.3.2 解决方案 363 9.3.3 工作原理 363 9.4 用REST服务发布JSON 372 9.4.1 问题 372 9.4.2 解决方案 372 9.4.3 工作原理 372 9.5 访问具有复杂XML响应的REST服务 375 9.5.1 问题 375 9.5.2 解决方案 375 9.5.3 工作原理 375 9.6 小结 385 第10 Spring和Flex 386 10.1 Flex入门 388 10.1.1 问题 388 10.1.2 解决方案 388 10.1.3 工作原理 388 10.2 离开沙箱 393 10.2.1 问题 393 10.2.2 解决方案 394 10.2.3 工作原理 394 10.3 为应用添加Spring BlazeDS支持 406 10.3.1 问题 406 10.3.2 解决方案 406 10.3.3 工作原理 406 10.4 通过BlazeDS/Spring暴露服务 411 10.4.1 问题 411 10.4.2 解决方案 411 10.4.3 工作原理 411 10.5 使用服务器端对象 418 10.5.1 问题 418 10.5.2 解决方案 418 10.5.3 工作原理 418 10.6 使用BlazeDS和Spring消费面向消息的服务 421 10.6.1 问题 421 10.6.2 解决方案 422 10.6.3 工作原理 422 10.7 将依赖注入带给你的ActionScript客户 434 10.7.1 问题 434 10.7.2 解决方案 434 10.7.3 工作原理 435 10.8 小结 439 第11 Grails 441 11.1 获取和安装Grails 441 11.1.1 问题 441 11.1.2 解决方案 442 11.1.3 工作原理 442 11.2 创建Grails应用 443 11.2.1 问题 443 11.2.2 解决方案 443 11.2.3 工作原理 443 11.3 Grails插件 447 11.3.1 问题 447 11.3.2 解决方案 448 11.3.3 工作原理 448 11.4 在Grails环境中开发、生产和测试 449 11.4.1 问题 449 11.4.2 解决方案 449 11.4.3 工作原理 450 11.5 创建应用的领域类 452 11.5.1 问题 452 11.5.2 解决方案 452 11.5.3 工作原理 452 11.6 为一个应用的领域类生成CRUD控制器和视图 454 11.6.1 问题 454 11.6.2 解决方案 454 11.6.3 工作原理 455 11.7 国际化(I18n)信息属性 458 11.7.1 问题 458 11.7.2 解决方案 458 11.7.3 工作原理 458 11.8 改变永久性存储系统 461 11.8.1 问题 461 11.8.2 解决方案 461 11.4.3 工作原理 461 11.9 日志 464 11.9.1 问题 464 11.9.2 解决方案 464 11.9.3 工作原理 464 11.10 运行单元和集成测试 466 11.10.1 问题 466 11.10.2 解决方案 467 11.10.3 工作原理 467 11.11 使用自定义布局和模板 472 11.11.1 问题 472 11.11.2 解决方案 472 11.11.3 工作原理 472 11.12 使用GORM查询 475 11.12.1 问题 475 11.12.2 解决方案 475 11.12.3 工作原理 475 11.13 创建自定义标记 477 11.13.1 问题 477 11.13.2 解决方案 477 11.13.3 工作原理 478 11.14 小结 479 第12 Spring Roo 481 12.1 设置Spring Roo开发环境 483 12.1.1 问题 483 12.1.2 解决方案 483 12.1.3 工作原理 483 12.2 创建第一个Spring Roo项目 486 12.2.1 问题 486 12.2.2 解决方案 486 12.2.3 工作原理 486 12.3 把现有项目导入SpringSource Tool Suite 491 12.3.1 问题 491 12.3.2 解决方案 492 12.3.3 工作原理 492 12.4 更快地构建更好的应用程序 493 12.4.1 问题 493 12.4.2 解决方案 494 12.4.3 工作原理 494 12.5 从项目中删除Spring Roo 500 12.5.1 问题 500 12.5.2 解决方案 500 12.5.3 工作原理 501 12.6 小结 502 第13 Spring测试 503 13.1 用JUnit and TestNG创建测试 504 13.1.1 问题 504 13.1.2 解决方案 504 13.1.3 工作原理 504 13.2 创建单元测试和集成测试 509 13.2.1 问题 509 13.2.2 解决方案 509 13.2.3 工作原理 510 13.3 Spring MVC控制器的单元测试 518 13.3.1 问题 518 13.3.2 解决方案 518 13.3.3 工作原理 518 13.4 管理集成测试中的应用上下文 520 13.4.1 问题 520 13.4.2 解决方案 520 13.4.3 工作原理 521 13.5 向集成测试注入测试夹具 526 13.5.1 问题 526 13.5.2 解决方案 526 13.5.3 工作原理 527 13.6 管理集成测试中的事务 530 13.6.1 问题 530 13.6.2 解决方案 530 13.6.3 工作原理 531 13.7 在集成测试中访问数据库 536 13.7.1 问题 536 13.7.2 解决方案 536 13.7.3 工作原理 537 13.8 使用Spring的常用测试注解 540 13.8.1 问题 540 13.8.2 解决方案 540 13.8.3 工作原理 541 13.9 小结 542 第14 Spring Portlet MVC框架 544 14.1 用Spring Portlet MVC开发一个简单的Portlet 544 14.1.1 问题 544 14.1.2 解决方案 545 14.1.3 工作原理 546 14.2 将Portlet请求映射到处理程序 553 14.2.1 问题 553 14.2.2 解决方案 553 14.2.3 工作原理 554 14.3 用简单的表单控制器处理portlet表单 561 14.3.1 问题 561 14.3.2 解决方案 561 14.3.3 工作原理 561 14.4 小结 569 第15 数据访问 570 15.1 Direct JDBC的问题 571 15.1.1 建立应用数据库 571 15.1.2 理解数据访问对象设计模式 573 15.1.3 用JDBC实现DAO 573 15.1.4 在Spring中配置数据源 575 15.1.5 运行DAO 577 15.1.6 更进一步 577 15.2 使用JDBC模板更新数据库 578 15.2.1 问题 578 15.2.2 解决方案 578 15.2.3 工作原理 578 15.3 使用JDBC模板查询数据库 583 15.3.1 问题 583 15.3.2 解决方案 583 15.3.3 工作原理 583 15.4 简化JDBC模板创建 588 15.4.1 问题 588 15.4.2 解决方案 588 15.4.3 工作原理 589 15.5 在Java 1.5中使用简单的JDBC模板 591 15.5.1 问题 591 15.5.2 解决方案 591 15.5.3 工作原理 591 15.6 在JDBC模板中使用命名参数 595 15.6.1 问题 595 15.6.2 解决方案 595 15.6.3 工作原理 595 15.7 在Spring JDBC框架中处理异常 597 15.7.1 问题 597 15.7.2 解决方案 597 15.7.3 工作原理 598 15.8 直接使用ORM框架的问题 602 15.8.1 问题 602 15.8.2 解决方案 603 15.8.3 工作原理 603 15.8.4 使用Hibernate API,用Hibernate XML映射持续化对象 604 15.8.5 使用Hibernate API,以JPA注解持续化对象 608 15.8.6 使用JPA,以Hibernate为引擎持续化对象 610 15.9 在Spring中配置ORM资源工厂 613 15.9.1 问题 613 15.9.2 解决方案 614 15.9.3 工作原理 614 15.10 用Spring ORM模板持续化对象 620 15.10.1 问题 620 15.10.2 解决方案 620 15.10.3 工作原理 621 15.11 用Hibernate的上下文会话持续化对象 626 15.11.1 问题 626 15.11.2 解决方案 626 15.11.3 工作原理 626 15.12 用JPA的上下文注入持续化对象 629 15.12.1 问题 629 15.12.2 解决方案 629 15.12.3 工作原理 630 15.13 小结 632 第16 Spring中的事务管理 634 16.1 事务管理的问题 635 16.2 选择一个事务管理器实现 641 16.2.1 问题 641 16.2.2 解决方案 641 16.2.3 工作原理 641 16.3 用事务管理器API编程管理事务 642 16.3.1 问题 642 16.3.2 解决方案 643 16.3.3 工作原理 643 16.4 用事务模板编程管理事务 644 16.4.1 问题 644 16.4.2 解决方案 645 16.4.3 工作原理 645 16.5 用事务通知声明式地管理事务 647 16.5.1 问题 647 16.5.2 解决方案 648 16.5.3 工作原理 648 16.6 用@Transactional注解声明式地管理事务 650 16.6.1 方法 650 16.6.2 解决方案 650 16.6.3 工作原理 650 16.7 设置事务传播属性 652 16.7.1 问题 652 16.7.2 解决方案 652 16.7.3 工作原理 653 16.8 设置隔离事务属性 657 16.8.1 问题 657 16.8.2 解决方案 657 16.8.3 工作原理 658 16.9 设置Rollback事务属性 664 16.9.1 问题 664 16.9.2 解决方案 664 16.9.3 工作原理 664 16.10 设置超时和只读事务属性 666 16.10.1 问题 666 16.10.2 解决方案 666 16.10.3 工作原理 666 16.11 用加载时织入管理事务 667 16.11.1 问题 667 16.11.2 解决方案 667 16.11.3 工作原理 667 16.12 小结 67117 EJB、Spring Remoting和Web服务 672 17.1 通过RMI暴露和调用服务 672 17.1.1 问题 672 17.1.2 解决方案 673 17.1.3 工作原理 673 17.2 用Spring创建EJB 2.x组件 676 17.2.1 问题 676 17.2.2 解决方案 677 17.2.3 工作原理 677 17.3 在Spring中访问遗留的EJB 2.x组件 683 17.3.1 问题 683 17.3.2 解决方案 683 17.3.3 工作原理 684 17.4 在Spring中创建EJB 3.0组件 687 17.4.1 问题 687 17.4.2 解决方案 687 17.4.3 工作原理 688 17.5 在Spring中访问EJB 3.0组件 689 17.5.1 问题 689 17.5.2 解决方案 690 17.5.3 工作原理 690 17.6 通过HTTP暴露和调用服务 692 17.6.1 问题 692 17.6.2 解决方案 692 17.6.3 工作原理 692 17.7 选择SOAP Web服务开发方法 696 17.7.1 问题 696 17.7.2 解决方案 696 17.7.3 工作原理 696 17.8 使用JAX-WS暴露和调用Contract-Last SOAP Web服务 698 17.8.1 问题 698 17.8.2 解决方案 698 17.8.3 工作原理 698 17.9 定义Web服务契约 705 17.9.1 问题 705 17.9.2 解决方案 705 17.9.3 工作原理 705 17.10 使用Spring-WS实现Web服务 709 17.10.1 问题 709 17.10.2 解决方案 709 17.10.3 工作原理 710 17.11 使用Spring-WS调用Web服务 715 17.11.1 问题 715 17.11.2 解决方案 715 17.11.3 工作原理 715 17.12 用XML编组开发Web服务 719 17.12.1 问题 719 17.12.2 解决方案 719 17.12.3 工作原理 720 17.13 用注解创建服务端点 724 17.13.1 问题 724 17.13.2 解决方案 725 17.13.3 工作原理 725 17.14 小结 726 第18 企业中的Spring 727 18.1 将Spring Bean输出为JMX MBean 727 18.1.1 问题 727 18.1.2 解决方案 728 18.1.3 工作原理 728 18.2 发布和监听JMX通知 740 18.2.1 问题 740 18.2.2 解决方案 740 18.2.3 工作原理 740 18.3 在Spring中访问远程JMX MBean 742 18.3.1 问题 742 18.3.2 解决方案 742 18.3.3 工作原理 742 18.4 用Spring电子邮件支持发送邮件 745 18.4.1 问题 745 18.4.2 解决方案 745 18.4.3 工作原理 746 18.5 用Spring的Quartz支持进行调度 753 18.5.1 问题 753 18.5.2 解决方案 753 18.5.3 工作原理 753 18.6 用Spring 3.0的调度命名空间进行调度 758 18.6.1 问题 758 18.6.2 解决方案 758 18.6.3 工作原理 758 18.7 小结 762 第19 消息 763 19.1 用Spring发送和接收JMS消息 764 19.1.1 问题 764 19.1.2 解决方案 765 19.1.3 工作原理 765 19.2 转换JMS消息 776 19.2.1 问题 776 19.2.2 解决方案 776 19.2.3 方法 776 19.3 管理JMS事务 778 19.3.1 问题 778 19.3.2 方法 779 19.3.3 解决方案 779 19.4 在Spring中创建消息驱动POJO 780 19.4.1 问题 780 19.4.2 解决方案 780 19.4.3 工作原理 781 19.5 建立连接 786 19.5.1 问题 786 19.5.2 解决方案 787 19.5.3 工作原理 787 19.6 小结 788 第20 Spring Integration 789 20.1 用EAI集成一个系统到另一个系统 790 20.1.1 问题 790 20.1.2 解决方案 790 20.1.3 工作原理 790 20.2 使用JMS集成两个系统 793 20.2.1 问题 793 20.2.2 解决方案 793 20.2.3 工作原理 793 20.3 查询Spring Integration消息得到上下文信息 797 20.3.1 问题 797 20.3.2 解决方案 797 20.3.3 工作原理 797 20.4 用一个文件系统集成两个系统 800 20.4.1 问题 800 20.4.2 解决方案 800 20.4.3 工作原理 800 20.5 将消息从一种类型转换为另一种类型 802 20.5.1 问题 802 20.5.2 解决方案 802 20.5.3 工作原理 803 20.6 使用Spring Integration进行错误处理 806 20.6.1 问题 806 20.6.2 解决方案 806 20.6.3 工作原理 806 20.7 集成控制分支:分解器和聚合器 809 20.7.1 问题 809 20.7.2 解决方案 809 20.7.3 工作原理 809 20.8 用路由器实现条件路由 813 20.8.1 问题 813 20.8.2 解决方案 813 20.8.3 工作原理 813 20.9 使外部系统适应总线 814 20.9.1 问题 814 20.9.2 解决方案 814 20.9.3 工作原理 814 20.10 用Spring Batch产生事件 825 20.10.1 问题 825 20.10.2 解决方案 825 20.10.3 工作原理 825 20.11 使用网关 826 20.11.1 问题 826 20.11.2 解决方案 826 20.11.3 工作原理 827 20.12 小结 832 第21 Spring Batch 834 21.1 建立Spring Batch的基础架构 836 21.1.1 问题 836 21.1.2 解决方案 836 21.1.3 工作原理 837 21.2 读取和写入(无计算) 839 21.2.1 问题 839 21.2.2 解决方案 839 21.2.3 工作原理 840 21.3 编写自定义ItemWriter和ItemReader 844 21.3.1 问题 844 21.3.2 解决方案 844 21.3.3 工作原理 844 21.4 在写入前处理输入 847 21.4.1 问题 847 21.4.2 解决方案 847 21.4.3 工作原理 847 21.5 通过事务改善生活 850 21.5.1 问题 850 21.5.2 解决方案 850 21.5.3 工作原理 850 21.6 重试 852 21.6.1 问题 852 21.6.2 解决方案 852 21.6.3 工作原理 852 21.7 控制步骤异常 855 21.7.1 问题 855 21.7.2 解决方案 856 21.7.3 工作原理 856 21.8 启动一个作业 860 21.8.1 问题 860 21.8.2 解决方案 860 21.8.3 工作原理 860 21.9 参数化一个作业 864 21.9.1 问题 864 21.9.2 解决方案 864 21.9.3 工作原理 864 21.10 小结 866 第22 网格上的Spring 867 22.1 使用Terracotta聚合对象状态 869 22.1.1 问题 869 22.1.2 解决方案 869 22.1.3 工作原理 869 22.2 将执行分布到网格上 879 22.2.1 问题 879 22.2.2 解决方案 879 22.2.3 方法 879 22.3 方法的负载平衡 880 22.3.1 问题 880 22.3.2 解决方案 881 22.3.3 方法 881 22.4 并行处理 884 22.4.1 问题 884 22.4.2 解决方案 885 22.4.3 方法 885 22.5 在GridGain上部署 887 22.5.1 问题 887 22.5.2 解决方案 887 22.5.3 工作原理 887 22.6 小结 891 第23 jBPM和Spring 893 软件过程 894 23.1 理解工作流模型 896 23.1.1 问题 896 23.1.2 解决方案 897 23.1.3 工作原理 897 23.2 安装jBPM 898 23.2.1 问题 898 23.2.2 解决方案 898 23.2.3 工作原理 898 23.3 将jBPM4与Spring整合 900 23.3.1 问题 900 23.3.2 解决方案 900 23.3.3 工作原理 900 23.4 用Spring构建一个服务 906 23.4.1 问题 906 23.4.2 解决方案 906 23.4.3 工作原理 907 23.5 构建业务过程 910 23.5.1 问题 910 23.5.2 解决方案 910 23.5.3 工作原理 910 23.6 小结 913 第24 OSGi和Spring 914 24.1 OSGi入门 915 24.1.1 问题 915 24.1.2 解决方案 915 24.1.3 工作原理 916 24.2 开始使用Spring Dynamic Modules 922 24.2.1 问题 922 24.2.2 解决方案 922 24.2.3 工作原理 922 24.3 用Spring Dynamic Modules输出服务 926 24.3.1 问题 926 24.3.2 解决方案 926 24.3.3 工作原理 926 24.4 在OSGi注册表中寻找一个具体服务 929 24.4.1 问题 929 24.4.2 解决方案 930 24.4.3 工作原理 930 24.5 发布多个接口的一个服务 932 24.5.1 问题 932 24.5.2 解决方案 932 24.5.3 工作原理 932 24.6 定制Spring Dynamic Modules 933 24.6.1 问题 933 24.6.2 解决方案 933 24.6.3 工作原理 933 24.7 使用SpringSource dm Server 935 24.7.1 问题 935 24.7.2 解决方案 935 24.7.3 工作原理 935 24.8 SpringSource的各类工具 937 24.8.1 问题 937 24.8.2 解决方案 937 24.8.3 工作原理 937 24.9 小结 938 文摘 版权页:
随着Spring框架最新版本——3.0版的发布,Spring平台已经发展成熟,成为JavaJava虚拟机、Groovy、NET或者Action-Script开发人员最强大、最具革命性的解决方案之一。 《Spring攻略(第2版)》是Spring平台的深入指南,它引导你进入Spring 3及其辅助框架的最新技术。《Spring攻略(第2版)》不仅为你全面而又深入地讲解各种概念,并且在每一中都配备了一系列详细的代码示例,以帮助读者在实际的工作中迅速应用于实战。 SpringSource为核心框架添加了许多部件。这些部件不仅简化了Java EE之上的API,并且为Java EE所忽略的问题提供了第一流的完整解决方案。构建于Spring IoC容器组件模型之上的这些Spring3部件提供了集成、批处理、OSGi、Ajax和Flex集成、状态式的Web应用、REST风格Web服务、富客户端用户界面、Google AppEngine开发、基于云的部署、消息、数据访问、Web服务等多种功能。而且,Spring能很好地与其他辅助框架(包括业务过程管理、群集缓冲以及网格计算)进行协作。 你在寻求和Ruby on Rails一样的一体化架构吗?那么你会被Grails等Spring替代方案所深深吸引,对于Groovy开发人员来说,Grails具有难以置信的能力和生产率。如果你是寻求快速、轻量级的应用构建方法的Java开发人员,你会喜欢上Spring Roo,它能让你快速地通过应用的原型阶段,进入维护阶段,形成清晰的、面向最佳实践的代码。 以上所有这些主题,在这本以丰富代码为基础攻略中都能找到。我们希望你能够享受Spring平台的学习和使用。 Gary Mak,Josh Long和Daniel Rubio。 作者简介 作者:(美国)麦克(Gary Mak) (美国)隆(Josh Long) (美国)卢比奥(Daniel Rubio) 译者:陈宗恒 姚军 蒋亮 麦克,Gary Mak,Meta-Archit软件技术有限公司的创立者及首席顾问。 隆,Josh Long,SpringSource的Spring开发倡导人。 卢比奥,Daniel Rubio,超过10年的企业级和Web开发经验顾问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值