1.Spring的简介
Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。
Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。
然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
范围:任何Java应用
简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
2.Spring的ioc
IOC:控制反转
2.1什么是控制反转?
将实例化对象的权利,由程序员来控制转交给Spring容器来控制(简单理解就是:将实例化对象交给Spring容器)
2.2spring的注入方式(set方法属性注入)
2.2.1修改我们maven项目的pom.xml文件(别客气c过去直接用)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>sptingIoc</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>sptingIoc Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <spring.version>5.0.1.RELEASE</spring.version> <javax.servlet.version>4.0.0</javax.servlet.version> <junit.version>4.12</junit.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- 2、导入spring依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <!-- 5.1、junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- 5.2、servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${javax.servlet.version}</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>sptingIoc</finalName> </build> </project>
2.2.2导入spring
2.2.3ioc使用
package xzs.ioc.serverce; /* 定义了一个用户更改个人信息的接口 */ public interface UserServerce { public void update(); }
package xzs.ioc.serverce.impl; import xzs.ioc.serverce.UserServerce; /* 客户需求: 需求客户登录后需要更改个人信息的功能 场景1: 客户要求,再新增的需求上做迭代版本,如上传头像 场景2: 客户要求再新增的需求上做优化,提升性能,图使用多线程 */ public class UserServerceImpl implements UserServerce { @Override public void update() { System.out.printf("更改个人信息的功能"); //添加上传头像功能的代码 //System.out.println("上传头像"); } }
package xzs.ioc.serverce.impl; import xzs.ioc.serverce.UserServerce; public class UserServerceImpl2 implements UserServerce { @Override public void update() { System.out.printf("更改个人信息的功能"); //添加上传头像功能的代码 System.out.println("上传头像"); } }
package xzs.ioc.web; import xzs.ioc.serverce.UserServerce; import xzs.ioc.serverce.impl.UserServerceImpl; /* 程旭员手动实例化对象的弊端 1.一旦依赖的接口实现需要大量改动。迭代。维护成本极高 2.当接口的实现类不统一,维护成本更高 */ public class userAction { private UserServerce userServerce; public UserServerce getUserServerce() { return userServerce; } public void setUserServerce(UserServerce userServerce) { this.userServerce = userServerce; } public String update(){ userServerce.update(); return "list"; } }
package xzs.ioc.web; import xzs.ioc.serverce.UserServerce; import xzs.ioc.serverce.impl.UserServerceImpl; import xzs.ioc.serverce.impl.UserServerceImpl2; public class GoodsAction { private UserServerce userServerce; public UserServerce getUserServerce() { return userServerce; } public void setUserServerce(UserServerce userServerce) { this.userServerce = userServerce; } public String update(){ userServerce.update(); return "list"; } }
以上我们模拟了若项目未达到项目的要求,要回去修改这里以修改个人信息为例。
若是靠程序员手动实例化对象这会出现以下问题
1.一旦依赖的接口实现需要大量改动。迭代。维护成本极高
2.当接口的实现类不统一,维护成本更高
所以这时候我们利用spring,ioc的特性控制转换’
<?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"> <!--凡是在spring文件配置中的,javabean交给spring配置文件管理如:这李userAction则是由spring-context来管理--> <bean class="xzs.ioc.web.userAction" id="userAction"> <property name="userServerce" ref="userServerce2"></property> </bean> <bean class="xzs.ioc.web.GoodsAction" id="GoodsAction"> <property name="userServerce" ref="userServerce"></property> </bean> <bean class="xzs.ioc.serverce.impl.UserServerceImpl2" id="userServerce"></bean> <bean class="xzs.ioc.serverce.impl.UserServerceImpl" id="userServerce2"></bean> </beans>
若客户想要用户有上传头像功能,商品没有我们只需有修改以上中的property中的ref属性改成
UserServer2即可,可以节约大量时间
结果:
2.3spring注入方式(构造注入)
package xzs.ioc.web; import xzs.ioc.serverce.UserServerce; import xzs.ioc.serverce.impl.UserServerceImpl; import xzs.ioc.serverce.impl.UserServerceImpl2; import java.util.List; public class GoodsAction { private UserServerce userServerce; private String gname;//商品名称 private int age;//保质期 private List<String> proples;//食用人群 public List<String> getProples() { return proples; } public void setProples(List<String> proples) { this.proples = proples; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGname() { return gname; } public void setGname(String gname) { this.gname = gname; } public UserServerce getUserServerce() { return userServerce; } public void setUserServerce(UserServerce userServerce) { this.userServerce = userServerce; } public String update(){ userServerce.update(); return "list"; } public void pros(){ System.out.println(this.gname); System.out.println(this.age); System.out.println(this.proples); } }
这里就添加有参,无参构造方法,那么spring文件配置则是
bean class="xzs.ioc.web.userAction" id="userAction"> <!-- <property name="userServerce" ref="userServerce"></property>--> <!-- <constructor-arg name="gname" value="小猪"></constructor-arg>--> <!-- <constructor-arg name="age" value="18"></constructor-arg>--> <!-- <constructor-arg name="hobby">--> <!-- <list>--> <!-- <value>唱</value>--> <!-- <value>跳</value>--> <!-- <value>rap</value>--> <!-- </list> </constructor-arg>--> </bean>
2.4spring注入方式(接口注入或者自动装配)
bytype:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" default-autowire="byType" 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"> <!--buname:javabean会根据属性名在spring上下文中进行寻找,根据spring上下文只能的bean的ID进行查找,只要有就会自动注入--> <!-- byType:会根据属性ing对应的接口类型,在spring的上下文是否有该接口的事项类,有就进行匹配,但是如皋找到两个以上这会报错或者没有--> <!--凡是在spring文件配置中的,javabean交给spring配置文件管理如:这李userAction则是由spring-context来管理--> <bean class="xzs.ioc.web.userAction" id="userAction"> <!-- <property name="userServerce" ref="userServerce"></property>--> <!-- <constructor-arg name="gname" value="小猪"></constructor-arg>--> <!-- <constructor-arg name="age" value="18"></constructor-arg>--> <!-- <constructor-arg name="hobby">--> <!-- <list>--> <!-- <value>唱</value>--> <!-- <value>跳</value>--> <!-- <value>rap</value>--> <!-- </list> </constructor-arg>--> </bean> <bean class="xzs.ioc.web.GoodsAction" id="GoodsAction"> <!-- <property name="userServerce" ref="userServerce"></property>--> <!-- <property name="gname" value="雨伞"></property>--> <!-- <property name="age" value="1"></property>--> <!-- <property name="proples">--> <!-- <list>--> <!-- <value>成年人</value>--> <!-- <value>留守儿童</value>--> <!-- </list>--> <!-- </property>--> </bean> <!-- <bean class="xzs.ioc.serverce.impl.UserServerceImpl2" id="userServerce"></bean>--> <bean class="xzs.ioc.serverce.impl.UserServerceImpl" id="userServerce2"></bean> </beans>
以上所示我们在beans中 xmlns属性下添加一个
default-autowire="byType"属性即可
byname:
将default-autowire="byType"替换成byName即可
注意:
2.5spring与web容器的整合
思考:
1.每一个请求建模都建模一程,十分消耗性能
2.希望只建模一次,然后每次请求都可以
3.监听器,将spring上下文放入上下文
首先创建一个listener的包
创建SpringLoadListner,将spring上下文放入其中如:
package xzs.ioc.listener; import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.servlet.*; import javax.servlet.annotation.WebListener; @WebListener public class SpringLoadLister implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("初始化:将spring上下文放入tomcat中去"); //将spring上下文放入tomcat上下文 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml"); //获取tomcat上下文 ServletContext servletContext= sce.getServletContext(); servletContext.setAttribute("springContext",context); } }
测试
创建一个userServlet类
package xzs.ioc.web; import org.springframework.context.support.ClassPathXmlApplicationContext; import xzs.ioc.serverce.UserServerce; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/userList") public class UserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //当处理客户请求分的时候,获取spring的上下文对象 ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) req.getServletContext().getAttribute("springContext"); UserServerce userService = (UserServerce) context.getBean("userService"); System.out.println(userService); userService.update(); } }
一个监听器就创建好了
结果: