第一章介绍
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
















