3.0、Spring-注入
一、Spring的基本介绍:Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。
1、核心思想:IOC(控制反转,或者成为反射)和AOP(面向切面编程),依赖注入(DI)和控制反转(IOC)是同一个概念的不同表述。
这篇帖子写得不错:http://jinnianshilongnian.iteye.com/blog/1413846;
2、作用:管理整个项目。
3、注入:在Spring的配置文件里配置Dao、Service、Action的Bean,并让Dao层引入数据源,Service引入Dao,Action引入Service。Dao层要继承数据源的对象HibernateDaoSupport,service要引入Dao的接口并添加Set方法。
四种依赖注入反式:setter注入、构造器注入、静态工厂的方法注入、实例工厂的方法注入。
4、切面:通知和切点就构成了切面。
二、注入举例:
1、创建一个新的项目,拷贝一个applicationContext.xml文件到src目录下面,添加Spring框架所需要的jar包:org.springframework.core/beans/context(先只添加这三个最主要的jar包,以后差什么根据提示再往里面加,一般加包的时候采用宁少勿多的原则)。
2、新建一个包:com.st.bean1,并在这个包下面新建一个UserBean类:
1 package com.st.bean1; 2 3 public class UserBean { 4 private String userName; 5 private String password; 6 7 8 @Override 9 public String toString() { 10 return "UserBean [userName=" + userName + ", password=" + password 11 + "]"; 12 } 13 public String getUserName() { 14 return userName; 15 } 16 public void setUserName(String userName) { 17 this.userName = userName; 18 } 19 public String getPassword() { 20 return password; 21 } 22 public void setPassword(String password) { 23 this.password = password; 24 } 25 }
3、编辑applicationContext.xml文件中的类容
1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <beans xmlns="http://www.springframework.org/schema/beans" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 9 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> 10 <bean id="user" class="com.st.bean1.UserBean"> 11 <!-- setter注入,依赖于set方法 --> 12 <property name="userName" value="陈泽俊"></property> 13 <property name="password" value="123456"></property> 14 </bean> 15 </beans>
4、新建一个测试类BeanTest1
1 package com.st.bean1; 2 3 4 import org.junit.Test; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 public class BeanTest1 { 9 @Test 10 public void test(){ 11 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 12 UserBean user = context.getBean("user",UserBean.class); 13 System.out.println(user); 14 } 15 }
5、更改配置文件applicationContext.xml中的类容实现构造器注入:
a)、在UserBean类中添带所有的参数加构造方法:(需要注意的是一般在添加了有参构造器的同时还添加一个无参构造器)
b)、修改.xml配置文件中的类容:
1 <bean id="user" class="com.st.bean1.UserBean"> 2 <!-- setter注入,依赖于set方法 --> 3 <!-- <property name="userName" value="陈泽俊"></property> 4 <property name="password" value="123456"></property> --> 5 6 <!-- 构造器注入,依赖于构造方法 --> 7 <!-- 方法一:必须要按构造方法的顺序来写 --> 8 <!-- <constructor-arg value="陈泽俊"/> 9 <constructor-arg value="234567"/> --> 10 11 <!-- 方法二:按构造方法的参数的顺序的小标来写,下标从0开始 --> 12 <!-- <constructor-arg index="1" value="234567"/> 13 <constructor-arg index="0" value="陈泽俊"/> --> 14 15 <!-- 方法三:直接通过构造方法的参数的属性名来写 --> 16 <constructor-arg name="userName" value="chenzejun" /> 17 <constructor-arg name="password" value="123456" /> 18 </bean>
6、如果新建一个类AddrBean:
1 package com.st.bean1; 2 3 public class AddrBean { 4 private String addr; 5 public String getAddr() { 6 return addr; 7 } 8 public void setAddr(String addr) { 9 this.addr = addr; 10 } 11 @Override 12 public String toString() { 13 return "AddrBean [addr=" + addr + "]"; 14 } 15 }
在UserBean中,引入这个类,即将AddrBean作为UserBean这个类中的一个属性:private AddrBean addr(注意添加set方法并重写toString方法);这时要在xml配置文件中注入addr就需要在xml文件中新建一个<bean>标签,再通过<property>标签中的ref属性将这个<bean>标签引入:
1 <bean id="user" class="com.st.bean1.UserBean"> 2 <constructor-arg name="userName" value="chenzejun" /> 3 <constructor-arg name="password" value="123456" /> 4 <property name="addr" ref="addr"/> 5 </bean> 6 <bean id="addr" class="com.st.bean1.AddrBean"> 7 <property name="addr" value="湖北民族学院"></property> 8 </bean>
(上面的配置文件中的<property> 标签中的类容也可以这样来写,但需要注意的是<ref>标签中bean和local属性的区别)
1 <property name="addr"> 2 <!-- 应用的整个Spring文件里面的 --> 3 <ref bean="addr"/> 4 </property> 5 <property name="addr" > 6 <!-- 引入的是本文件里面的 --> 7 <ref local="addr"/> 8 </property>
这时可用上面的BeanTest1类中的test方法进行测试:输出为“UserBean [userName=chenzejun, password=123456, addr=AddrBean [addr=湖北民族学院]]”。
7、在实际开发过程中,一般会有多个Spring的配置文件,这时可以设置一个总的.xml文件,在这个文件里面引入其他的xml文件。就像Struts2配置中,每个Bean类都对应的有一个xml文件,但是这些xml文件都被映射到struts2.xml文件中,最终只需要引入struts2.xml文件即可。以上面的第6步为例:
a)、复制一个applicationContext.xml文件到com.st.bean1这个包下面,并重命名为applicationContext1.xml,并编写的关于AddrBean这个类的注入方式:
1 <bean id="address" class="com.st.bean1.AddrBean"> 2 <property name="addr" value="湖北民族学院" /> 3 </bean>
b)、在applicationContext.xml文件中通过<import>标签引入applicationContext1.xml文件,再用6中的方式一样可以达到相同的效果:
1 <import resource="com/st/bean1/applicationContext1.xml"/> 2 <bean id="user" class="com.st.bean1.UserBean"> 3 <constructor-arg name="userName" value="chenzejun" /> 4 <constructor-arg name="password" value="123456" /> 5 <property name="addr" ref="address"/> 6 </bean> 7 </beans>
8、数组的注入
a)新建一个包com.st.bean2,在包里面添加一个CollectionBean类:
1 package com.st.bean2; 2 3 import java.util.List; 4 import java.util.Map; 5 6 public class CollectionBean { 7 private String name; 8 private List<String> list; 9 private Map<String,Object> map; 10 @Override 11 public String toString() { 12 return "CollectionBean [name=" + name + ", list=" + list + ", map=" 13 + map + "]"; 14 } 15 public String getName() { 16 return name; 17 } 18 public void setName(String name) { 19 this.name = name; 20 } 21 public List<String> getList() { 22 return list; 23 } 24 public void setList(List<String> list) { 25 this.list = list; 26 } 27 public Map<String, Object> getMap() { 28 return map; 29 } 30 public void setMap(Map<String, Object> map) { 31 this.map = map; 32 } 33 }
b)、在applicationContext.xml文件中添加collection的注入配置
1 <bean id="collection" class="com.st.bean2.CollectionBean"> 2 <property name="name" value="张三"/> 3 <!-- 设定list集合中注入的数据 --> 4 <property name="list" > 5 <list> 6 <value>张三</value> 7 <value>李四</value> 8 <value>王五</value> 9 </list> 10 </property> 11 <!-- 设定注入map集合中的数据 --> 12 <property name="map"> 13 <map> 14 <!-- 设定键值和数据 --> 15 <entry key="key1" value="小明"/> 16 <entry key="key2" value="小红"/> 17 <entry key="key3" value="小黑"/> 18 </map> 19 </property> 20 21 </bean>
c)、在TestBean中添加测试代码:
1 @Test 2 public void test(){ 3 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 4 CollectionBean collection = context.getBean("collection",CollectionBean.class); 5 System.out.println(collection); 6 }
d)、输出结果为“CollectionBean [name=张三, list=[张三, 李四, 王五], map={key1=小明, key2=小红, key3=小黑}]”。
三、Spring Web应用举例:
1、在上述项目的基础上新建四个包 com.st.bean/dao/service/servlet 并在这些包中添加相应的接口和实现类:
a)、在bean下面创建UserBean类:
1 package com.st.bean; 2 3 public class UserBean { 4 private String userName; 5 private String password; 6 public String getUserName() { 7 return userName; 8 } 9 public void setUserName(String userName) { 10 this.userName = userName; 11 } 12 public String getPassword() { 13 return password; 14 } 15 public void setPassword(String password) { 16 this.password = password; 17 } 18 @Override 19 public String toString() { 20 return "UserBean [userName=" + userName + ", password=" + password 21 + "]"; 22 } 23 }
b)、在dao下面添加UserDao接口及该接口的实现类UserDaoIm,实现类的类容为:
1 package com.st.dao; 2 3 import com.st.bean.UserBean; 4 5 public class UserDaoIm implements UserDao { 6 public UserBean queryUser(UserBean user) { 7 System.out.println(user); 8 return user; 9 } 10 }
c)、在service中添加UserService接口,并添加该接口的实现类UserServiceIm,实现类中的类容为:
1 package com.st.service; 2 3 import com.st.bean.UserBean; 4 import com.st.dao.UserDao; 5 6 public class UserServiceIm implements UserService { 7 8 private UserDao dao; 9 public UserBean queryUser(UserBean user) { 10 return dao.queryUser(user); 11 } 12 public void setDao(UserDao dao) { 13 this.dao = dao; 14 } 15 }
d)、在applicationContext.xml文件中配置注入:
1 <bean id="userDao" class="com.st.dao.UserDaoIm"></bean> 2 <bean id="userService" class="com.st.service.UserServiceIm"> 3 <property name="dao" ref="userDao"></property> 4 </bean>
e)、在index.jsp页面编写一个简单的登陆界面:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 <title>用户登陆</title> 12 </head> 13 <body> 14 <form method="post" action="<%=request.getContextPath()%>/userServlet"> 15 <table> 16 <tr> 17 <td>用户名:</td> 18 <td><input type="text" id="userName" name="userName" value=""/></td> 19 </tr> 20 <tr> 21 <td>密 码:</td> 22 <td><input type="password" id="password" name="password" value=""/></td> 23 </tr> 24 <tr> 25 <td><input type="submit" value="登陆"/></td> 26 <td><input type="reset" value="重置"/></td> 27 </tr> 28 </table> 29 </form> 30 </body> 31 </html>
f)、在web.xml文件中添加servlet的配置:
1 <servlet> 2 <servlet-name>userServlet</servlet-name> 3 <servlet-class>com.st.servlet.UserServlet</servlet-class> 4 </servlet> 5 <servlet-mapping> 6 <servlet-name>userServlet</servlet-name> 7 <url-pattern>/userServlet</url-pattern> 8 </servlet-mapping>
g)、在servlet中添加UserServlet类(注意不要忘记了该类需要继承HttpServlet类):
1 package com.st.servlet; 2 3 import java.io.IOException; 4 5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 10 import org.springframework.context.ApplicationContext; 11 import org.springframework.context.support.ClassPathXmlApplicationContext; 12 13 import com.st.bean.UserBean; 14 import com.st.service.UserService; 15 16 public class UserServlet extends HttpServlet{ 17 18 @Override 19 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 20 throws ServletException, IOException { 21 UserBean user = new UserBean(); 22 user.setUserName(req.getParameter("userName")); 23 user.setPassword(req.getParameter("password")); 24 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 25 UserService service = context.getBean("userService", UserService.class); 26 UserBean user1 = service.queryUser(user); 27 } 28 @Override 29 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 30 throws ServletException, IOException { 31 this.doGet(req, resp); 32 } 33 }
上述就是Spring框架的一个简单的搭建过程,Spring的作用就是管理整个项目。