1.Spring简介,有什么作用及其好处
Spring主要的作用是解耦,用于降低组件与组件关系,提高了程序结构的灵活性.在项目中主要使用该框架的IOC和AOP两个特性.
2.IOC概念
Inverse of Contorl 反向控制,控制反转
控制权是指对象的创建和调用的关系指定.
3.Spring入门示例 HelloWorld!
1)引入spring开发包
spring.jar,commons-logging.jar
2)在src下添加spring配置文件
applicationContext.xml
1 2 3 |
< ?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:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" default-lazy-init="true"> </beans> |
3)将程序的Bean组件在spring配置中定义,交给spring框架管理
Bean组件由spring框架负责创建和调用关系指定.
—->HelloBeanZh
MessageBean—>HelloBean—|
—->HelloBeanEn
HelloBean组件:
1 2 3 4 5 |
package com.weishuzhai.bean; public interface HelloBean { public void say(); } |
HelloBeanZh组件:
1 2 3 4 5 6 7 8 9 |
package com.weishuzhai.bean; public class HelloBeanZh implements HelloBean { public void say() { System.out.println("---- 你好,欢迎学习spring! ----"); } } |
MessageBean组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.weishuzhai.bean; public class MessageBean { private HelloBean hello; public void show() { System.out.println("---- 消息如下: ----"); hello.say(); } public HelloBean getHello() { return hello; } public void setHello(HelloBean hello) { this.hello = hello; } } |
各组件在spring配置文件 applicationContext.xml中的配置:
1 2 3 4 5 6 7 |
< ?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:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" default-lazy-init="true"> <bean id="helloBean" class="com.weishuzhai.bean.HelloBeanZh"/> <bean id="messageBean" class="com.weishuzhai.bean.MessageBean"> <property name="hello" ref="helloBean"></property> </bean> </beans> |
进行测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.weishuzhai.bean.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.weishuzhai.bean.MessageBean; public class TestMessageBean { // test1写法出现空指针异常,应该如test2方法。 // @Test public void test1() { MessageBean bean = new MessageBean(); bean.show(); } @Test public void test2() { String[] configs = { "applicationContext.xml" }; ApplicationContext ac = new ClassPathXmlApplicationContext(configs); MessageBean message = (MessageBean) ac.getBean("messageBean"); message.show(); } } |
运行结果:
4. Spring基础
1)Spring容器实例化
a. ApplicationContext (容器对象,可使用getBean()方法)
优先于BeanFactory,功能比BeanFactory强大.
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
b.BeanFactory(提供了对象创建\关系\定位等功能)
XMLBeanFactory
2)Spring容器对对象的管理
a.如何使容器管理某个组件
1 |
<bean id="标识符" class="包名.类型"/> |
b.对象创建时机
默认情况下,bean对象是在容器创建时也一起创建出来.
可以在xml配置中使用配置,指定延迟创建Bean对象.
1 |
<beans default-lazy-init="true"></beans> |
控制所有Bean组件。
1 |
<bean lazy-init="true"></bean> |
控制某一个Bean组件。
c.容器创建Bean对象的模式
默认采用singleton(单例)模式.可以使用下面方法改变:
1 |
<bean scope="prototype"/> |
每次调用getBean()将返回一个新实例.
如果应用在Web环境中,还可以指定request,session等
d.指定初始化方法和销毁方法
1 |
<bean init-method="" destroy-method=""/> |
注意:destroy-method对scope=”singleton”才有使用意义
UserBean.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.weishuzhai.bean; public class UserBean { public UserBean() { System.out.println("-----构造方法,创建UserBean对象------"); } public void myInit() { System.out.println("------初始化方法myInit------"); } public void myDestroy() { System.out.println("------销毁方法myDestroy------"); } } |
配置文件applicationContext.xml:
1 2 3 4 5 |
< ?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:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" default-lazy-init="true"> <bean id="userBean" class="com.weishuzhai.bean.UserBean" scope="singleton" init-method="myInit" destroy-method="myDestroy"></bean> </beans> |
测试执行TestApplicationContext.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package com.weishuzhai.bean.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.weishuzhai.bean.UserBean; public class TestApplicationContext { // @Test public void test1() { ApplicationContext ac = new ClassPathXmlApplicationContext( "applicationContext.xml"); UserBean user = (UserBean) ac.getBean("userBean"); } @Test public void test2() { AbstractApplicationContext ac = new ClassPathXmlApplicationContext( "applicationContext.xml"); UserBean user = (UserBean) ac.getBean("userBean"); UserBean user1 = (UserBean) ac.getBean("userBean"); System.out.println(user == user1); ac.close(); } } |
运行结果:test1和test2同时执行
3)DI依赖注入(是实现IOC的重要技术)
a.setter方式注入
(1)在对象中定义一个属性及setter方法,属性推荐使用接口
PersonBean.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
package com.weishuzhai.bean; 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 PersonBean { private int id; private String name; private int age; private List<string> loves = new ArrayList</string><string>(); private Set</string><string> cities = new HashSet</string><string>(); private Map</string><string , String> books = new HashMap</string><string , String>(); private Properties pros = new Properties(); private HelloBean hello; public void show() { System.out.println("----通过Setter注入了以下信息-----"); System.out.println("编号" + id); System.out.println("姓名" + name); System.out.println("年龄" + age); System.out.println("----爱好---"); for (String love : loves) { System.out.println(love); } System.out.println("----城市----"); for (String city : cities) { System.out.println(city); } System.out.println("----图书信息----"); Set</string><string> keys = books.keySet(); for (String key : keys) { System.out.println(key + " " + books.get(key)); } System.out.println("-----网址--------"); Set<object> ids = pros.keySet(); for (Object id : ids) { System.out.println(id + " " + pros.get(id)); } System.out.println("------HelloBean-----"); hello.say(); } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Map<string , String> getBooks() { return books; } public void setBooks(Map</string><string , String> books) { this.books = books; } public Set</string><string> getCities() { return cities; } public void setCities(Set</string><string> cities) { this.cities = cities; } public HelloBean getHello() { return hello; } public void setHello(HelloBean hello) { this.hello = hello; } public int getId() { return id; } public void setId(int id) { this.id = id; } public List</string><string> getLoves() { return loves; } public void setLoves(List</string><string> loves) { this.loves = loves; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Properties getPros() { return pros; } public void setPros(Properties pros) { this.pros = pros; } } |
(2)在spring配置中,利用
1 |
<property name="属性名"></property> |
指定参数值
applicationContext.xml配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
< ?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:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" default-lazy-init="true"> <!-- setter方式注入各种类型的信息 --> <bean id="personBean" class="com.weishuzhai.bean.PersonBean"> <property name="id"> <value>1001</value> </property> <property name="name"> <value>Sealter</value> </property> <property name="age"> <value>23</value> </property> <property name="loves"> <list> <value>旅游</value> <value>游泳</value> <value>编程</value> </list> </property> <property name="cities"> <set> <value>北京</value> <value>上海</value> <value>青岛</value> </set> </property> <property name="books"> <map> <entry key="1001" value="Java编程基础"></entry> <entry key="1002" value="Java高级编程"></entry> <entry key="1003" value="Java框架方案"></entry> <entry key="1004" value="Java设计模式"></entry> <entry key="1005" value="编程之美"></entry> </map> </property> <property name="pros"> <props> <prop key="1">www.weishuzhai.com</prop> <prop key="2">www.taoxiaotan.com</prop> <prop key="3">www.sina.com</prop> </props> </property> <property name="hello" ref="helloBean"></property> </bean> </beans> |
测试执行:
TestPersonBean.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.weishuzhai.bean.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.weishuzhai.bean.PersonBean; import com.weishuzhai.bean.UserBean1; public class TestPersonBean { @Test public void test1() { String[] configs = { "applicationContext.xml" }; ApplicationContext ac = new ClassPathXmlApplicationContext(configs); PersonBean person = (PersonBean) ac.getBean("personBean"); person.show(); } } |
运行结果:
b.构造方法注入
(1)在对象中定义一个带参数的构造方法
UserBean1.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.weishuzhai.bean; public class UserBean1 { private int id; private String name; private int age; public UserBean1(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } public void show() { System.out.println("----通过构造注入了以下信息-----"); System.out.println("编号" + id); System.out.println("姓名" + name); System.out.println("年龄" + age); } } |
(2)在spring配置中,利用
1 |
<constructor -arg index="0"></constructor> |
指定参数值
applicationContext.xml配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
< ?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:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" default-lazy-init="true"> <!-- 构造方法注入各种类型的信息 --> <bean id="userBean1" class="com.weishuzhai.bean.UserBean1"> <constructor -arg index="0"> <value>1001</value> </constructor> <constructor -arg index="1"> <value>Sealter</value> </constructor> <constructor -arg index="2"> <value>23</value> </constructor> </bean> </beans> |
测试执行 TestPresonBean.java中的test2方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.weishuzhai.bean.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.weishuzhai.bean.PersonBean; import com.weishuzhai.bean.UserBean1; public class TestPersonBean { @Test public void test2() { String[] configs = { "applicationContext.xml" }; ApplicationContext ac = new ClassPathXmlApplicationContext(configs); UserBean1 user = (UserBean1) ac.getBean("userBean1"); user.show(); } } |
运行结果:
c.接口注入
附注:name属性和id属性的区别:name可以使用特殊字符,比如”/”。一般使用id属性