第一章介绍

spring简介

官方网站:http://spring.io/ 下载地址:https:///libs-release-local/org/springframework/spring/ 核心思想:IOC控制反转;AOP面向切面
Spring默认是以单例形式管理Bean
介绍:Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。

框架的特性:
1轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。
2控制反转——Spring通过一种称作控制反转(IoC)的技术促进了低耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
3面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。
4容器——Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。
5框架——Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。
6MVC——Spring的作用是整合,但不仅仅限于整合,Spring 框架可以被看做是一个企业解决方案级别的框架。客户端发送请求,服务器控制器(由DispatcherServlet实现的)完成请求的转发,控制器调用一个用于映射的类HandlerMapping,该类用于将请求映射到对应的处理器来处理请求。HandlerMapping 将请求映射到对应的处理器Controller(相当于Action)在Spring 当中如果写一些处理器组件,一般实现Controller 接口,在Controller 中就可以调用一些Service 或DAO 来进行数据操作 ModelAndView 用于存放从DAO 中取出的数据,还可以存放响应视图的一些数据。 如果想将处理结果返回给用户,那么在Spring 框架中还提供一个视图组件ViewResolver,该组件根据Controller 返回的标示,找到对应的视图,将响应response 返回给用户。
所有Spring的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。

spring4版helloworld实现

让spring来管理一个helloworld类的实例
新建项目Spring401
->新建文件夹spring导入lib核心jar包
commons-collections-3.2.jar
commons-logging.jar
spring-aop-4.0.6.release.jar
spring-beans-4.0.6.release.jar
spring-context-4.0.6.release.jar
spring-core-4.0.6.release.jar
spring-expression-4.0.6.release.jar
然后要bulid path
->新建包com.java1234.test
新建类HelloWorld.java

package com.java1234.test;

public class HelloWorld {

	public void say(){
		System.out.println("Spring4你好!");
	}
}

->新建包com.java1234.service
新建类Test.java

package com.java1234.service;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.java1234.test.HelloWorld;

public class Test {

	public static void main(String[] args) {
		ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");//加载spring的beans
		HelloWorld helloWorld=(HelloWorld)ac.getBean("helloWorld");//获取到spring管理的bean
		helloWorld.say();
	}
}

用到的API:ApplicationContext ClassPathXmlApplicationContext
->新建beans.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="helloWorld" class="com.java1234.test.HelloWorld"></bean>  //用spring的方式new一个bean
</beans>

->启动程序:
控制台上输出“Spring4你好!”
说明我们获取到了bean

第二章 Spring之IOC详解

一.spring IOC简介

IOC(控制反转:Inverse of Control),又称依赖注入,是一种重要的面向对象编程法则来削弱计算机程序的耦合问题,也是轻量级的Spring框架的核心。

二.spring IOC实例讲解

控制权转从业务代码转到主管手上
通过xml文件将实例依赖注入到某个类的属性中,底层原理还是依靠反射
任务:主管找个人来测试程序
新建项目Spring402
->com.java1234.service
新建类Zhangsan.java

package com.java1234.service;

public class ZhangSan{

	public void test(){
		System.out.println("张三-测试程序");
	}
}

->com.java1234.service
新建类JavaWork.java

package com.java1234.service;

public class JavaWork {
	public void doTest(){
		ZhangSan zhangsan=new ZhangSan();
		zhangsan.test();
	}
}

->com.java1234.test
新建测试类Test.java

package com.java1234.test;

import com.java1234.service.JavaWork;
import com.java1234.service.Lisi;

public class Test {

	/**
	 * 主管执行命令
	 * @param args
	 */
	public static void main(String[] args) {
		JavaWork javaWork=new JavaWork();
		javaWork.doTest();
	}
}

->执行程序:执行测试类
控制台上打印出“张三-测试程序”
意思是张三这个人去做测试这件事
但是这时候,测试这个类和人这个类是完全耦合在一起的。若现在是让李四去做,还需要改掉以上的很多代码,改动太大。
这时就出现一种设计思路,控制反转。让每个人执行测试工作转交给主管。
->com.java1234.service
定义一个接口
Tester.java

package com.java1234.service;

public interface Tester {

	public void test();
}

->然后让张三继承自这个接口
ZhangSan.java

package com.java1234.service;

public class ZhangSan implements Tester{

	public void test(){
		System.out.println("张三-测试程序");
	}
}

->让李四也实现这个接口
Lisi.java

package com.java1234.service;

public class Lisi implements Tester{

	public void test(){
		System.out.println("李四-测试程序");
	}
}

->在JavaWork.java中定义一个测试员tester,具体是哪个测试员,我们从主管那里设置。

package com.java1234.service;

public class JavaWork {
	
	private Tester tester;
	
	public void setTester(Tester tester) {
		this.tester = tester;
	}

	public void doTest(){
		tester.test();//这个程序只是负责有个人来做测试,而不管具体的某个人
	}
}

->

javaWork.setTester(new ZhangSan());
javaWork.setTester(new Lisi());

->com.java1234.test
Test.java

package com.java1234.test;

import com.java1234.service.JavaWork;
import com.java1234.service.Lisi;

public class Test {

	/**
	 * 主管执行命令
	 * @param args
	 */
	public static void main(String[] args) {
		JavaWork javaWork=new JavaWork();
		// javaWork.setTester(new ZhangSan());//这是我们需要设置一个人来做测试
		javaWork.setTester(new Lisi());
		javaWork.doTest();
	}
}

->启动程序
控制台打印出相应的是张三在测试还是李四在测试
这样的话,控制权就不是由业务代码(JavaWork)来搞了,而是转交给主管了(Test)。

以上依然是要写个命令,接下来我们用spring来管理
->beans.xml
<?xml version="1.0" encoding="UTF-8"?>

<bean id="zhangsan" class="com.java1234.service.ZhangSan"></bean>
	
	<bean id="lisi" class="com.java1234.service.Lisi"></bean>
	
	<bean id="javaWork" class="com.java1234.service.JavaWork">
		<property name="tester" ref="lisi"></property>//包含tester属性,这里要让谁做就将谁设置进去
	</bean>
  
</beans>

->这时就不要Test.java了
Test2.java

package com.java1234.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.java1234.service.JavaWork;

public class Test2 {

	public static void main(String[] args) {
		ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
		JavaWork javaWork=(JavaWork)ac.getBean("javaWork");//获取javaWork bean
		javaWork.doTest();
	}
}

->启动程序:
启动测试类,执行出相应的人去测试

三.装配一个bean

在xml文件里面配置
id是javabean的唯一标识,通过id可以取出bean的实例

四.依赖注入

1.属性注入

新建项目Spring402-02
->新建com.java1234.entity People.java

package com.java1234.entity;

public class People {

	private int id;
	private String name;
	private int age;

	public People() {
		super();
		// TODO Auto-generated constructor stub
	}

	public People(int id, String name, int age) {
		super();
		this.id = id;
		 = name;
		this.age = age;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		 = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "People [id=" + id + ", name=" + name + ", age=" + age + "]";
	}   	
}

->beans.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="people" class="com.java1234.entity.People"></bean>
	
</beans>

->com.java1234.test Test2.java

package com.java1234.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.java1234.entity.People;


public class Test2 {

	public static void main(String[] args) {
		ApplicationContext ac=new    ClassPathXmlApplicationContext("beans.xml");
		People people=(People)ac.getBean("people");
		System.out.println(people);
		
	}
}

->启动程序
控制台上输出People[id=0,name=null,age=0]
这个很容易懂,就是加载了一个bean
以下我们可以通过依赖注入给它注入一些属性
->beans.xml中多加一个bean

<bean id="people2" class="com.java1234.entity.People">
	<property name="id" value="1"></property>
	<property name="name" value="张三"></property>
	<property name="age" value="11"></property>
</bean>

->Test2.java

// 属性注入
    		People people2=(People)ac.getBean("people2");
    		System.out.println(people2);

->启动程序
控制台上输出People[id=1,name=张三,age=11]
说明属性已经注入进去了

2.构造函数注入;(通过类型,通过索引,联合使用)

通过类型,按照构造方法的参数注入
->beans.xml

<bean id="people3" class="com.java1234.entity.People">
		<constructor-arg type="int" value="2"></constructor-arg>
		<constructor-arg type="String" value="李四"></constructor-arg>
		<constructor-arg type="int" value="22"></constructor-arg>
	</bean>

->Test2.java

// 构造方法注入
    		People people3=(People)ac.getBean("people3");
    		System.out.println(people3);

->启动程序
控制台上打印出People[id=2,name=李四,age=22]
通过索引,按照构造方法的顺序注入
->beans.xml

<bean id="people4" class="com.java1234.entity.People">
    		<constructor-arg index="0" value="3"></constructor-arg>
    		<constructor-arg index="1" value="王五"></constructor-arg>
    		<constructor-arg index="2" value="55"></constructor-arg>
    	</bean>

->Test2.java

People people4=(People)ac.getBean("people4");
        		System.out.println(people4);

->启动程序
控制台上打印出People[id=3,name=王五,age=55]
联合使用
->beans.xml

<bean id="people5" class="com.java1234.entity.People">
    		<constructor-arg index="0" type="int" value="4"></constructor-arg>
    		<constructor-arg index="1" type="String" value="招六"></constructor-arg>
    		<constructor-arg index="2" type="int" value="66"></constructor-arg>
    	</bean>

->Test2.java

People people5=(People)ac.getBean("people5");
		System.out.println(people5);

->启动程序
控制台上打印出People[id=4,name=赵六,age=66]

3.工厂方法注入(非静态工厂,静态工厂)

工厂是用来造东西的
->com.java1234.factory
PeopleFactory.java

package com.java1234.factory;

import com.java1234.entity.People;

public class PeopleFactory {

	public People createPeople(){
		People p=new People();
		p.setId(5);
		p.setName("小七");
		p.setAge(77);
		return p;
	}
}

->beans.xml

<bean id="peopleFactory" class="com.java1234.factory.PeopleFactory"></bean>
//指定是哪个工厂、工厂的哪个方法
<bean id="people7" factory-bean="peopleFactory" factory-method="createPeople"></bean>

->Test2.java

// 工厂方法注入
    		People people7=(People)ac.getBean("people7");
    		System.out.println(people7);

->启动程序
控制台上打印出People[id=5,name=小七,age=77]
静态工厂
->com.java1234.factory
PeopleFactory2.java

package com.java1234.factory;

import com.java1234.entity.People;

public class PeopleFactory2 {

	public static People createPeople(){
		People p=new People();
		p.setId(8);
		p.setName("小八");
		p.setAge(88);
		return p;
	}
}

->beans.xml

//静态的话,是不用new实例的,直接用类名.方法调用
	<bean id="people8" class="com.java1234.factory.PeopleFactory2" factory-method="createPeople"></bean>

->Test2.java

// 工厂方法注入
    		People people8=(People)ac.getBean("people8");
			System.out.println(people8);

->启动程序
控制台上打印出People[id=8,name=小八,age=88]

4.泛型依赖注入(Spring4整合Hibernate4的时候顺带讲)

五.注入参数

1.基本类型值

对应第三讲的属性注入
新建项目Spring402-03
->导入测试包,新建junit包,中导入junit4.4 add build path添加到路径中去
->com.java1234.test
新建Junit test case
T.java

package com.java1234.test;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.java1234.entity.People;

public class T {

	private ApplicationContext ac;
	//只要一个setup方法,只需要在方法调用之前执行一下ClassPathXmlApplicationContext方法就行,要把ApplicationContext声明在外边,不然别的方法用不了
	@Before
	public void setUp() throws Exception {
		ac=new ClassPathXmlApplicationContext("beans.xml");
	}

	
}

->People.java

package com.java1234.entity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class People {

	private int id;
	private String name;
	private int age;
	
	public People() {
		super();
		// TODO Auto-generated constructor stub
	}
	public People(int id, String name, int age) {
		super();
		this.id = id;
		 = name;
		this.age = age;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		 = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "People [id=" + id + ", name=" + name + ", age=" + age
				+ "]";
	}
}

->beans.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="people1" class="com.java1234.entity.People">
		<property name="id" value="1"></property>
		<property name="name" value="张三"></property>
		<property name="age" value="11"></property>
	</bean>
	
</beans>

->T.java

// 基本类型值
	@Test
	public void test1() {
		People people=(People)ac.getBean("people1");
		System.out.println(people);
	}

->启动程序 T.java test1() run as junit test
控制台上输出People[id=1,name=张三 ,age=11]

2.注入bean

->com.java1234.entity
Dog.java

package com.java1234.entity;

public class Dog {

	private String name;

	public String getName() {
		return name;
	}

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

->beans.xml

<bean id="dog1" class="com.java1234.entity.Dog">
    		<property name="name" value="Jack"></property>
    	</bean>

->People.java 将Dog作为People的一个属性

package com.java1234.entity;

public class People {

	private int id;
	private String name;
	private int age;
	private Dog dog;
	public People() {
		super();
		// TODO Auto-generated constructor stub
	}
	public People(int id, String name, int age) {
		super();
		this.id = id;
		 = name;
		this.age = age;
	}
	public Dog getDog() {
		return dog;
	}
	public void setDog(Dog dog) {
		this.dog = dog;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		 = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "People [id=" + id + ", name=" + name + ", age=" + age
				+ ", dog=" + dog.getName() +  "]";
	}
}

->beans.xml

<bean id="people2" class="com.java1234.entity.People">
	<property name="id" value="1"></property>
	<property name="name" value="张三"></property>
	<property name="age" value="11"></property>
	<property name="dog" ref="dog1"></property>
</bean>

->T.java

// 注入bean
	@Test
	public void test2() {
		People people=(People)ac.getBean("people2");
		System.out.println(people);
	}

->启动程序test2() junit test
控制台上打印出People[id=1,name=张三 ,age=11,dog=Jack]

3.注入内部bean

people2可以引用,people1也可以引用
->beans.xml 这里就不是引用了,而是在内部写bean

<bean id="people3" class="com.java1234.entity.People">
    		<property name="id" value="1"></property>
    		<property name="name" value="张三"></property>
    		<property name="age" value="11"></property>
    		<property name="dog">
    			<bean class="com.java1234.entity.Dog">
    				<property name="name" value="Tom"></property>
    			</bean>
    		</property>
    	</bean>

->T.java

// 内部bean
@Test
public void test3() {
	People people=(People)ac.getBean("people3");
	System.out.println(people);
}

->启动程序test3() junit test
控制台上打印出People[id=1,name=张三 ,age=11,dog=Tom]

某个对象单独使用的bean

4.null值

有人没有狗,必须给他注入一个null标签
->beans.xml

<bean id="people4" class="com.java1234.entity.People">
    		<property name="id" value="1"></property>
    		<property name="name" value="张三"></property>
    		<property name="age" value="11"></property>
    		<property name="dog">
    			<null></null>
    		</property>
    	</bean>

->T.java

// 注入null
	@Test
	public void test4() {
		People people=(People)ac.getBean("people4");
		System.out.println(people);
	}

->启动程序
控制台上打印出People[id=1,name=张三 ,age=11,dog=null]

5.级联属性

注入当前对象的成员变量(也是对象)的属性
我们这边不用引入bean的形式
->beans.xml

<bean id="people5" class="com.java1234.entity.People">
    		<property name="id" value="1"></property>
    		<property name="name" value="张三"></property>
    		<property name="age" value="11"></property>
    		<property name="" value="Jack2">//这样赋值不常用
    		</property>
    	</bean>

->直接用会报错
T.java

// 级联属性
@Test
public void test5() {
	People people=(People)ac.getBean("people5");
	System.out.println(people);
}

->启动程序报错
->所以用级联的话,必须自己new一个
People.java
private Dog dog=new Dog();
控制台上打印出People[id=1,name=张三 ,age=11,dog=null]

6.集合类型属性

List
->People.java

import java.util.ArrayList;
import java.util.List;
private List<String> hobbies=new ArrayList<String>();
public List<String> getHobbies() {
	return hobbies;
}
public void setHobbies(List<String> hobbies) {
	this.hobbies = hobbies;
}

->beans.xml

<bean id="people6" class="com.java1234.entity.People">
    		<property name="id" value="1"></property>
    		<property name="name" value="张三"></property>
    		<property name="age" value="11"></property>
    		<property name="dog" ref="dog1"></property>
    		<property name="hobbies">
    			<list>
    				<value>唱歌</value>
    				<value>跳舞</value>
    			</list>
    		</property>	
    		</property>
    	</bean>

->T.java

// 注入集合
@Test
public void test6() {
	People people=(People)ac.getBean("people6");
	System.out.println(people);
}

->启动程序
控制台上输出People[id=1,name=张三,age=11,dog=Jack,hobbies=[唱歌,跳舞]]
Set不能重复
->Peolple.java

import java.util.HashSet;
import java.util.Set;
private Set loves=new HashSet();
public Set getLoves() {
return loves;
}
public void setLoves(Set loves) {
this.loves = loves;
}
->beans.xml

<bean id="people6" class="com.java1234.entity.People">
    		<property name="id" value="1"></property>
    		<property name="name" value="张三"></property>
    		<property name="age" value="11"></property>
    		<property name="dog" ref="dog1"></property>
    		<property name="hobbies">
    			<list>
    				<value>唱歌</value>
    				<value>跳舞</value>
    			</list>
    		</property>	
    		<property name="loves">
    			<set>
    				<value>唱歌2</value>
    				<value>跳舞2</value>
    			</set>
    		</property>
    		</property>
    	</bean>

->启动程序
控制台上输出People[id=1,name=张三,age=11,dog=Jack,hobbies=[唱歌,跳舞],loves=[唱歌2,跳舞2]]
Map
->People.java

import java.util.HashMap;
import java.util.Map;
private Map<String,String> works=new HashMap<String,String>();

	public Map<String, String> getWorks() {
		return works;
	}
	public void setWorks(Map<String, String> works) {
		this.works = works;
	}

->beans.xml

<property name="works">
    			<map>
    				<entry>
    					<key><value>上午</value></key>
    					<value>写代码</value>
    				</entry>
    				<entry>
    					<key><value>下午</value></key>
    					<value>测试代码</value>
    				</entry>
    			</map>
    		</property>

->启动程序
控制台上输出People[id=1,name=张三,age=11,dog=Jack,hobbies=[唱歌,跳舞],loves=[唱歌2,跳舞2],works={上午=写代码,下午=测试代码}]
Properties
->People.java

import java.util.Properties;
private Properties addresses=new Properties();
public Properties getAddresses() {
		return addresses;
	}
	public void setAddresses(Properties addresses) {
		this.addresses = addresses;
	}

->beans.xml

<property name="addresses">
    			<props>
    				<prop key="address1">aaaaa</prop>
    				<prop key="address2">bbbbb</prop>
    			</props>
    			</property >

->启动程序
控制台上输出People[id=1,name=张三,age=11,dog=Jack,hobbies=[唱歌,跳舞],loves=[唱歌2,跳舞2],works={上午=写代码,下午=测试代码},addresses={address2=bbbbb,address1=aaaaa}]

六.自动装配(很少用)

通过配置 default-autowire 属性,Spring IOC 容器可以自动为程序注入 bean;默认是 no,不启用自动装配;
default-autowire 的类型有 byName,byType,constructor; byName:通过名称进行自动匹配;
byType:根据类型进行自动匹配;
constructor:和 byType 类似,只不过它是根据构造方法注入而言的,根据类型,自动注入;
建议:自动装配机制慎用,它屏蔽了装配细节,容易产生潜在的错误;项目不是很大时或者命名很规范可以用
byName
新建项目Spring402-04
->以前都是自己手动注入,现在加一个配置就可以自动注入了
beans.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"
        default-autowire="byName">
        //default-autowire="byName"这就是通过名字自动注入

	
	<bean id="dog" class="com.java1234.entity.Dog">
		<property name="name" value="Jack"></property>
	</bean>
	<bean id="dog2" class="com.java1234.entity.Dog">
		<property name="name" value="Tom"></property>
	</bean>
	
	
	<bean id="people1" class="com.java1234.entity.People">
		<property name="id" value="1"></property>
		<property name="name" value="张三"></property>
		<property name="age" value="11"></property>
	</bean>
	
</beans>

->T.java

package com.java1234.test;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.java1234.entity.People;

public class T {

	private ApplicationContext ac;

	@Before
	public void setUp() throws Exception {
		ac=new ClassPathXmlApplicationContext("beans.xml");
	}

	@Test
	public void test1() {
		People people=(People)ac.getBean("people1");
		System.out.println(people);
	}
	

}

->启动程序
控制台上打印出People[id=1,name=张三,age=11,dog=Jack]
我们都没有写dog属性的配置,它都自己注入了
byType
新建项目Spring402-04
->以前都是自己手动注入,现在加一个配置就可以自动注入了
beans.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"
        default-autowire="byType">
        //default-autowire="byType"这就是通过类型自动注入

	
	<bean id="dog2" class="com.java1234.entity.Dog">
		<property name="name" value="Tom"></property>
	</bean>
	
	
	<bean id="people1" class="com.java1234.entity.People">
		<property name="id" value="1"></property>
		<property name="name" value="张三"></property>
		<property name="age" value="11"></property>
	</bean>
	
</beans>

->T.java

package com.java1234.test;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.java1234.entity.People;

public class T {

	private ApplicationContext ac;

	@Before
	public void setUp() throws Exception {
		ac=new ClassPathXmlApplicationContext("beans.xml");
	}

	@Test
	public void test1() {
		People people=(People)ac.getBean("people1");
		System.out.println(people);
	}
	

}

->启动程序
控制台上打印出People[id=1,name=张三,age=11,dog=Tom]
当我们有两个dog的bean时他不识别,但是只有一个dogbean时就会自动识别
constructor
新建项目Spring402-04
->以前都是自己手动注入,现在加一个配置就可以自动注入了
beans.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"
        default-autowire="constructor">
        //default-autowire="constructor"这就是通过构造方法自动注入

	
	<bean id="dog2" class="com.java1234.entity.Dog">
		<property name="name" value="Jack"></property>
	</bean>
	
	
	<bean id="people1" class="com.java1234.entity.People">
		<property name="id" value="1"></property>
		<property name="name" value="张三"></property>
		<property name="age" value="11"></property>
	</bean>
	
</beans>

->People.java写构造方法

public People() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	
	public People(Dog dog) {
		super();
		System.out.println("constructor");
		this.dog = dog;
	}

->T.java

package com.java1234.test;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.java1234.entity.People;

public class T {

	private ApplicationContext ac;

	@Before
	public void setUp() throws Exception {
		ac=new ClassPathXmlApplicationContext("beans.xml");
	}

	@Test
	public void test1() {
		People people=(People)ac.getBean("people1");
		System.out.println(people);
	}
	

}

->启动程序
constructor
控制台上打印出People[id=1,name=张三,age=11,dog=Jack]

七.方法注入(很少用)

Spring bean作用域默认是 单例 singleton;可以通过配置prototype,实现多例;
方法注入 lookup-method
新建项目Spring402-05
每次获取狗都是得到一个新的狗
->People.java

package com.java1234.entity;


public abstract class People {

	private int id;
	private String name;
	private int age;
	private Dog dog;
	
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		 = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public  Dog getDog();
	
	public void setDog(Dog dog) {
		this.dog = dog;
	}
	@Override
	public String toString() {
		return "People [id=" + id + ", name=" + name + ", age=" + age
				+ ", dog=" + dog.getName() + "]";
	}

}

->beans.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="dog" class="com.java1234.entity.Dog">
		<property name="name" value="Jack"></property>
	</bean>
	
	
	<bean id="people1" class="com.java1234.entity.People">
		<property name="id" value="1"></property>
		<property name="name" value="张三"></property>
		<property name="age" value="11"></property>
	</bean>
	
</beans>

->T.java

package com.java1234.test;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.java1234.entity.People;

public class T {

	private ApplicationContext ac;

	@Before
	public void setUp() throws Exception {
		ac=new ClassPathXmlApplicationContext("beans.xml");
	}

	@Test
	public void test1() {
		System.out.println(ac.getBean("dog")==ac.getBean("dog"));//true
		//说明这是同一个对象
	}
	

}

这时改为单例
->beans.xml

//scope="prototype"来设置单例
<bean id="dog" class="com.java1234.entity.Dog" scope="prototype">
	<property name="name" value="Jack"></property>
</bean>

->T.java

System.out.println(ac.getBean("dog")==ac.getBean("dog"));//false
    		//说明这不是同一个对象

这时我们把狗注入给people
->beans.xml

<bean id="dog" class="com.java1234.entity.Dog" scope="prototype">
		<property name="name" value="Jack"></property>
</bean>

<bean id="people1" class="com.java1234.entity.People">
	<property name="id" value="1"></property>
	<property name="name" value="张三"></property>
	<property name="age" value="11"></property>
	<property name="dog" ref="dog"></property>

</bean>

->T.java

@Test
public void test1() {
	People people=(People)ac.getBean("people1");
	People people2=(People)ac.getBean("people1");
	System.out.println(people.getDog()==people2.getDog());
	
	System.out.println(ac.getBean("dog")==ac.getBean("dog"));
}

->输出
true 说明这是同一条狗,注入的时候规定死了是同一条狗
false
这时那我们还有办法么,有,改为抽象的方法
->People.java

public abstract Dog getDog();

->beans.xml

<bean id="dog" class="com.java1234.entity.Dog" scope="prototype">
		<property name="name" value="Jack"></property>
	</bean>
	
	<bean id="people1" class="com.java1234.entity.People">
		<property name="id" value="1"></property>
		<property name="name" value="张三"></property>
		<property name="age" value="11"></property>
		<lookup-method name="getDog" bean="dog"/>
	</bean>

//这样的话,每次就动态获取一个新的dog
->启动程序
false
false

八.方法切换(很少用)

新建项目Spring402-06
->People.java

package com.java1234.entity;


public class People {

	private int id;
	private String name;
	private int age;
	private Dog dog;
	
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		 = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	public Dog getDog() {//getDog方法写死
		Dog dog=new Dog();
		dog.setName("Jack");
		return dog;
	}
	public void setDog(Dog dog) {
		this.dog = dog;
	}
	@Override
	public String toString() {
		return "People [id=" + id + ", name=" + name + ", age=" + age
				+ ", dog=" + dog.getName() + "]";
	}
	
}

->People2.java

package com.java1234.entity;


public class People2{

	
}

假如说自己获取狗时,不想获取自己的Jack狗,而是想获取people2的Tom狗。这时候需要让people2实现一个接口和方法
->People2.java

package com.java1234.entity;

import java.lang.reflect.Method;

import org.springframework.beans.factory.support.MethodReplacer;


public class People2 implements MethodReplacer {

	@Override
	public Object reimplement(Object arg0, Method arg1, Object[] arg2)
			throws Throwable {
		Dog dog=new Dog();
		dog.setName("Tom");
		return dog;
	}
}

->beans.xml

<bean id="people1" class="com.java1234.entity.People">
		<property name="id" value="1"></property>
		<property name="name" value="张三"></property>
		<property name="age" value="11"></property>
		<replaced-method name="getDog" replacer="people2"></replaced-method>
	</bean>
	
	<bean id="people2" class="com.java1234.entity.People2"></bean>

->T.java

@Test
public void test1() {
	People people=(People)ac.getBean("people1");
	System.out.println(people.getDog().getName());
}

->运行结果
Tom

九.bean之间的关系

继承
依赖
引用
新建项目Spring402-07

继承

->People.java

package com.java1234.entity;


public class People {

	private int id;
	private String name;
	private int age;
	private String className;

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		 = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getClassName() {
		return className;
	}
	public void setClassName(String className) {
		this.className = className;
	}
	
	@Override
	public String toString() {
		return "People [id=" + id + ", name=" + name + ", age=" + age
				+ ", className=" + className +  "]";
	}
}

->beans.xml

//定义抽象bean,一些公共的属性
	<bean id="abstractPeople" class="com.java1234.entity.People" abstract="true">
		<property name="className" value="高三5班"></property>
		<property name="age" value="19"></property>
	</bean>
	//定义具体的bean
	<bean id="zhangsan" parent="abstractPeople">
		<property name="id" value="1"></property>
		<property name="name" value="张三"></property>
	</bean>
	
	<bean id="lisi" parent="abstractPeople">
		<property name="id" value="2"></property>
		<property name="name" value="李四"></property>
		<property name="age" value="20"></property>
	</bean>

->T.java

@Test
	public void test1() {
		People zhangsan=(People)ac.getBean("zhangsan");
		System.out.println(zhangsan);
		
		People lisi=(People)ac.getBean("lisi");
		System.out.println(lisi);
	}

->输出结果
People[id=1,name=张三,age=19,className=高三5班]
People[id=2,name=李四,age=20,className=高三5班]

依赖

查看李四时必须要有权限
->新建com.java1234.service
Authority.java

package com.java1234.service;

public class Authority {

	public Authority() {
		System.out.println("获取权限");
	}
}

->people.java

package com.java1234.entity;


public class People {

	private int id;
	private String name;
	private int age;
	private String className;
	
	//写一个默认的构造方法
	public People() {
		System.out.println("初始化People");
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		 = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getClassName() {
		return className;
	}
	public void setClassName(String className) {
		this.className = className;
	}

	@Override
	public String toString() {
		return "People [id=" + id + ", name=" + name + ", age=" + age
				+ ", className=" + className + "]";
	}

}

->beans.xml

<bean id="abstractPeople" class="com.java1234.entity.People" abstract="true">
	<property name="className" value="高三5班"></property>
	<property name="age" value="19"></property>
</bean>

<bean id="zhangsan" parent="abstractPeople">
	<property name="id" value="1"></property>
	<property name="name" value="张三"></property>
</bean>

<bean id="lisi" parent="abstractPeople">
	<property name="id" value="2"></property>
	<property name="name" value="李四"></property>
	<property name="age" value="20"></property>
</bean>

<bean id="autority" class="com.java1234.service.Authority"></bean>

->T.java

@Test
	public void test1() {
		People zhangsan=(People)ac.getBean("zhangsan");
		System.out.println(zhangsan);
		
		People lisi=(People)ac.getBean("lisi");
		System.out.println(lisi);
	}

->执行结果:这样的话是按照顺序加载的
初始化People
初始化People
获取权限
People[id=1,name=张三,age=19,className=高三5班]
People[id=2,name=李四,age=20,className=高三5班]
但是我们应该是先获取权限再初始化people呀,这时就要配置依赖关系
->beans.xml

<bean id="abstractPeople" class="com.java1234.entity.People" abstract="true">
	<property name="className" value="高三5班"></property>
	<property name="age" value="19"></property>
</bean>
//这样,加载zhangsanbean的时候,先去加载autoritybean
<bean id="zhangsan" parent="abstractPeople" depends-on="autority">
	<property name="id" value="1"></property>
	<property name="name" value="张三"></property>
</bean>

<bean id="lisi" parent="abstractPeople">
	<property name="id" value="2"></property>
	<property name="name" value="李四"></property>
	<property name="age" value="20"></property>
</bean>

<bean id="autority" class="com.java1234.service.Authority"></bean>

->执行结果:
获取权限
初始化People
初始化People
People[id=1,name=张三,age=19,className=高三5班]
People[id=2,name=李四,age=20,className=高三5班]

引用

->Dog.java

package com.java1234.entity;

public class Dog {

	private String name;

	public String getName() {
		return name;
	}

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

->People.java

package com.java1234.entity;


public class People {

	private int id;
	private String name;
	private int age;
	private String className;
	private Dog dog;
	
	
	public People() {
		System.out.println("初始化People");
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		 = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getClassName() {
		return className;
	}
	public void setClassName(String className) {
		this.className = className;
	}
	
	
	public Dog getDog() {
		return dog;
	}
	public void setDog(Dog dog) {
		this.dog = dog;
	}
	@Override
	public String toString() {
		return "People [id=" + id + ", name=" + name + ", age=" + age
				+ ", className=" + className + ", dog=" + dog + "]";
	}
}

->beans.xml

<bean id="dog" class="com.java1234.entity.Dog">
		<property name="name" value="jack"></property>
	</bean>
	
	<bean id="abstractPeople" class="com.java1234.entity.People" abstract="true">
		<property name="className" value="高三5班"></property>
		<property name="age" value="19"></property>
	</bean>
	
	<bean id="zhangsan" parent="abstractPeople" depends-on="autority">
		<property name="id" value="1"></property>
		<property name="name" value="张三"></property>
	</bean>
	
	<bean id="lisi" parent="abstractPeople">
		<property name="id" value="2"></property>
		<property name="name" value="李四"></property>
		<property name="age" value="20"></property>
		<property name="dog" ref="dog"></property>
	</bean>
	
	
	<bean id="autority" class="com.java1234.service.Authority"></bean>

->启动程序
获取权限
初始化People
初始化People
People[id=1,name=张三,age=19,className=高三5班,dog=null]
People[id=2,name=李四,age=20,className=高三5班,dog=com.java1234.entity.ddffw@23]

十.bean的作用范围

1,singletonSpring ioc 容器中仅有一个 Bean 实例,Bean 以单例的方式存在;
2,prototype 每次从容器中调用 Bean 时,都返回一个新的实例;
3,request 每次 HTTP 请求都会创建一个新的 Bean;
4,session 同一个 HTTPSession 共享一个 Bean;
5,globalsession 同一个全局 Session 共享一个 Bean,一般用于 Portlet 应用环境;
6,application 同一个 Application 共享一个 Bean
新建项目Sprign402-08
->Dog.java

package com.java1234.entity;

public class Dog {

	private String name;

	public String getName() {
		return name;
	}

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

->beans.xml

<bean id="dog" class="com.java1234.entity.Dog">
	<property name="name" value="jack"></property>
</bean>

->T.java

@Test
	public void test1() {
		Dog dog=(Dog)ac.getBean("dog");
		Dog dog2=(Dog)ac.getBean("dog");
		System.out.println(dog==dog2);
	}

->执行结果
true
说明默认模式是单例
->beans.xml

<bean id="dog" class="com.java1234.entity.Dog" scope="prototype">
	<property name="name" value="jack"></property>
</bean>

这时候返回false