目录
1、Spring的介绍
1.1 什么是Spring?
Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。
1.2 Spring能够做什么?
Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情, 然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
范围:任何Java应用
注:Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架
2、Spring中IOC的用途
2.1控制反转
接下来我们创建一个Maven的 项目,关于项目的创建小编在上篇文章讲述了Maven
但在Pom.xml中,放入一下代码,目的:将当前项目所用的jar包依赖版本定义在外部,目的在于所有jar包版本进行统一管理
<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>
创建一个接口UserBiz(用户业务类)类
一个接口必然有一个实现类,创建实现类
UserBizImpl1:
创建Web:
OrderAction:
UserAction:
一开始用户
需求:
同时在用户模块、订单模块拿到所有的用户数据
需求变更:
同时在用户模块、订单模块拿到所有的用户数据,并且要求用户数据是已经通过年龄排序了的
对应策略:修改userBiz中的list方法,添加排序功能
当客户需求再次变更2:
同时在用户模块、订单模块拿到所有的用户数据,并且要求用户数据是已经注册的时间点排序的
对应策略:修改UserBiz中的list方法,修改sql语句,添加排序功能,按照时间点排序
- 需求2:
我们将我们的实现类UserBizImpl1按照年龄排序
package com.zwc.biz.impl;
import com.zwc.biz.UserBiz;
public class UserBizImpl1 implements UserBiz{
@Override
public void list() {
System.out.println("查询用户数据,按照年龄排序。。。。。。");
}
}
- 再次建一个实现类,按照时间点排序
package com.zwc.biz.impl;
import com.zwc.biz.UserBiz;
public class UserBizImpl2 implements UserBiz{
@Override
public void list() {
System.out.println("查询用户数据,按照入职时间排序。。。。。。");
}
}
这样的好处:当客户的需求又要改变时,我们可以在userAction中改变new 对象将‘1’改成‘2’
以上我们可以得到总结:
- 最原始的方法:频繁修改业务层biz层代码,但频繁的修改会使代码报错
- 多实现的方法:凡是涉及到用户业务层调用的地方,都需要修改代码
——————————————————————————————————————
现在采用一个Spring做法:
- 首先将Spring的配置文件放入
- 注意:配置时要连接网络
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
</beans>
关于Spring IOC的作用:
管理整个项目的javaBean通过 依赖注入、控制反转 的特点进行管理
将我们创建的四个类配置到Spring 配置文件中
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- IOC的主要作用管理整个项目的javaBean,依赖注入、控制反转的特点进行管理 -->
<bean class="com.zwc.biz.impl.UserBizImpl1" id="userBiz1"> </bean>
<bean class="com.zwc.biz.impl.UserBizImpl2" id="userBiz2"> </bean>
<bean class="com.zwc.web.UserAction" id="userAction"> </bean>
<bean class="com.zwc.web.OrderAction" id="orderAction"> </bean>
</beans>
下一步我们可以将userAction的实例化对象注释掉,给userbiz提供get、set方法
package com.zwc.web;
import com.zwc.biz.UserBiz;
import com.zwc.biz.impl.UserBizImpl1;
import com.zwc.biz.impl.UserBizImpl2;
public class userAction {
// private UserBiz userBiz = new UserBizImpl2();
private UserBiz userBiz;
public UserBiz getUserBiz() {
return userBiz;
}
public void setUserBiz(UserBiz userBiz) {
this.userBiz = userBiz;
}
public void list() {
userBiz.list();
}
}
进入配置,ref依赖你想用那个实现类,就放入该id,
将我们的OrderAction进行修改
package com.zwc.web;
import com.zwc.biz.UserBiz;
import com.zwc.biz.impl.UserBizImpl1;
import com.zwc.biz.impl.UserBizImpl2;
public class OrderAction {
//private UserBiz userBiz = new UserBizImpl2();
private UserBiz userBiz;
public UserBiz getUserBiz() {
return userBiz;
}
public void setUserBiz(UserBiz userBiz) {
this.userBiz = userBiz;
}
public void list() {
userBiz.list();
}
}
进入配置进行修改
现在我们进行测试看有没有效果:
测试类:
package com.zwc.ioc.demo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zwc.web.UserAction;
public class Demo1 {
@SuppressWarnings("resource")
public static void main(String[] args) {
//Spring建模 spring-context.xml配置文件 Spring上下文
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
//拿到javaBean
UserAction userAction = (UserAction) context.getBean("userAction");
userAction.list();
}
}
- Spring的运行逻辑:
1、对Spring框架的配置文件进行建模,建模之后spring-context.xml中所有的javaBean信息都会加载进Spring 容器的上下文
2、上下文就包含了spring-context.xml 所有对象
Spring只需要我们修改配置文件,我们将UserBizImpl2改成1
测试:
可以看到结果,按照年龄排序
所以,当我们需要改变需求时,只需要修改配置文件就可以了
- 结论:IOC特点:控制反转
指的是将创建对象的犬粮反转给Spring容器来完成
—————————————————————————————————————
3.Spring的注入方式
3.1 set注入
注入三个属性,提供get、set方法
private String name;
private int age;
private List<String > hobby;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<String> getHobby() {
return hobby;
}
public void setHobby(List<String> hobby) {
this.hobby = hobby;
}
在配置中配置,我们这里不用ref,配置的是值,而上面的是对象
测试:
结果,可以看到拿到值:
3.2 构造注入
在我们OderAction同样放入三个元素,给他提供构造方法
package com.zwc.web;
import java.util.List;
import com.zwc.biz.UserBiz;
import com.zwc.biz.impl.UserBizImpl1;
import com.zwc.biz.impl.UserBizImpl2;
public class OrderAction {
//private UserBiz userBiz = new UserBizImpl2();
private UserBiz userBiz;
public UserBiz getUserBiz() {
return userBiz;
}
public void setUserBiz(UserBiz userBiz) {
this.userBiz = userBiz;
}
private String name;
private int age;
private List<String > hobby;
public OrderAction(String name, int age, List<String> hobby) {
super();
this.name = name;
this.age = age;
this.hobby = hobby;
}
public OrderAction() {
// TODO Auto-generated constructor stub
}
public void list() {
userBiz.list();
}
}
在配置文件配置OrderAction:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- IOC的主要作用管理整个项目的javaBean,依赖注入、控制反转的特点进行管理 -->
<bean class="com.zwc.biz.impl.UserBizImpl1" id="userBiz"> </bean>
<!-- set注入 -->
<bean class="com.zwc.web.UserAction" id="userAction">
<property name="userBiz" ref="userBiz"></property>
<property name="name" value="zhansan"></property>
<property name="age" value="22"></property>
<property name="hobby">
<list>
<value>篮球</value>
<value>rap</value>
<value>唱</value>
</list>
</property>
</bean>
<bean class="com.zwc.web.OrderAction" id="orderAction">
<property name="userBiz" ref="userBiz"></property>
<!-- 构造注入 -->
<constructor-arg name="name" value="zhangsan"></constructor-arg>
<constructor-arg name="age" value="23"></constructor-arg>
<constructor-arg name="hobby" >
<list>
<value>篮球</value>
<value>rap</value>
<value>唱</value>
</list>
</constructor-arg>
</bean>
</beans>
测试:
在lsit方法中打印
在demo1测试:
同样可以看到控制台已打印
3.3 自动装配
3.3.1byName
在我们如果有几十个属性的话,那我们在配置文件里的信息可能有许多代码
所以自动装配就发挥了作用
我们先将OrderAction里的property注释掉
测试,可以看到报空指针,那是因为没有注入
我们加入default-autowire=“byName”
测试,可以看到控制台已没有报错:
总结:通过使用byName我们可以不用引用实现类,它会主动帮我们引入进来
———————————————————————————————————————
3.3.2byType
但如果我们给属性换个名字的话,在使用byName就会报错,byName是通过名字进行查询,当你修改名字时,它查询不到,必然报错
而将byName改成byType的话就不会报错
byType是通过类型查询的,而我们的userAction是一个接口类,所以我们注入的都是一个实现类
——————————————————————————————————————
而当我们在加入一个实现类
测试,报错,出现了两个实现类,它不知道要把属性那个注入:
总结:
byName:通过Spring管理的bean对象的id进行查找,如果找不到则注入失败,反之成功
byType:根据Spring管理的bean接口实现类进行查找,如果没有或两个以上则注入失败,反之成功
4、Spring与Web项目的整合
最后我们Spring肯定要与Web进行整合,在这里我们的Servlet不可能每次都要写如图所示,这会耗时间:
WHy:建模的过程是十分耗时
解决问题:
1、建模过程必不可少
2、建模要保障只执行一次
3、建模后期望在每一个servlet都能购拿到Spring的上下文对象ClassPathXmlApplicationContext
HOW如何解决:
1、监听器的初始化方法
2、Spring的上下文要存放在tomcat的上下文中
创建一个监听器,实现监听器,初始化方法快捷Alt+Shift+s
代码如下:
package com.zwc.ioc.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zwc.web.UserAction;
public class SpringLoadListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce) {
// 拿到Spring的上下文
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
ServletContext servletContext = sce.getServletContext();
// 将Spring的上下文保持到Tomcat上下文中
servletContext.setAttribute("springContext", context);
}
}
测试:
@WebServlet("/springDemo")
public class DemoServlet extends HttpServlet{
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
// ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) req.getServletContext().getAttribute("springContext");
UserAction userAction = (UserAction) context.getBean("userAction");
userAction.list();
}
}
在这里我们还要配置Web.xml监听器
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Archetype Created Web Application</display-name>
<listener>
<listener-class>com.zwc.ioc.listener.SpringLoadListener</listener-class>
</listener>
</web-app>
在这里我们不可能配置文件是同一个名
我们在web.xml配置
<context-param>
<param-name>springconfiglocation</param-name>
<param-value>/applicationContext.xml</param-value>
</context-param>
若有错误,请各位指教