目录
一、对Spring的理解
二、Spring中IOC的特点
三、依赖注入的3种方式
四、Spring与web容器的整合
五、总结
1、Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。
Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。
然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
如下图(Spring所包含的功能):
范围:任何Java应用
简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
struts2
spring
hibernate
在Spring 出现之前,框架之间都必须相互整合:
而Spring出现之后,各框架只需要跟Spring整合即可:
JavaBean 项目中的一个个类
IOC和AOP
首先新建一个maven项目,注意要先导入jar依赖:
4.0.0
com.zking
T280_spring
war
0.0.1-SNAPSHOT
T280_spring Maven Webapp
http://maven.apache.org
5.0.1.RELEASE
4.0.0
4.12
junit
junit
3.8.1
test
org.springframework
spring-context
${spring.version}
org.springframework
spring-aspects
${spring.version}
junit
junit
${junit.version}
test
javax.servlet
javax.servlet-api
${javax.servlet.version}
provided
T280_spring
org.apache.maven.plugins
maven-compiler-plugin
3.7.0
1.8
UTF-8
关于Spring中IOC的特点,我们拿一个 用户业务类来作为案例,
比如说有客户,它提出需求:同时在用户模块、订单模块拿到所有的用户数据。
需求总是会有所变更,
需求变更1:
同时在用户模块、订单模块拿到所有的用户数据,并且要求用户数据是已经通过年龄排序了的。
对应策略:修改userBiz中的list方法,添加排序功能,按照年龄排序
需求变更2:
同时在用户模块、订单模块拿到所有的用户数据,并且要求用户数据是已经通过注册的时间点排序了的。
对应策略:修改userBiz中的list方法,添加排序功能,按照时间点排序
总结:
以上的对应策略是我们最原始的方法,弊端:频繁修改业务层biz层代码。
同时还有一个多实现方法,弊端:凡是涉及到用户业务层调用的地方,都需要修改代码。
因此我们的SpringIOC就来了:
biz层:
package com.ycx.biz;
/**
* 用户业务类
* @author 杨总
*
*/
public interface UserBiz {
void list();
}
web层:
package com.ycx.web;
import com.ycx.biz.UserBiz;
import com.ycx.biz.impl.UserBizImpl1;
import com.ycx.biz.impl.UserBizImpl2;
public class UserAction {
// private UserBiz userBiz=new UserBizImpl1();
private UserBiz userBiz;
public UserBiz getUserBiz() {
return userBiz;
}
public void setUserBiz(UserBiz userBiz) {
this.userBiz = userBiz;
}
public void list() {
userBiz.list();
}
}
Spring 配置文件:
package com.ycx.web;
import com.ycx.biz.UserBiz;
import com.ycx.biz.impl.UserBizImpl1;
import com.ycx.biz.impl.UserBizImpl2;
public class OrderAction {
// private UserBiz userBiz=new UserBizImpl1();
private UserBiz userBiz;
public UserBiz getUserBiz() {
return userBiz;
}
public void setUserBiz(UserBiz userBiz) {
this.userBiz = userBiz;
}
public void list() {
userBiz.list();
}
}
实现类:
UserBizImpl1 :
package com.ycx.biz.impl;
import com.ycx.biz.UserBiz;
public class UserBizImpl1 implements UserBiz{
@Override
public void list() {
System.out.println("查询用户数据...通过年龄排序...");
}
}
package com.ycx.biz.impl;
import com.ycx.biz.UserBiz;
public class UserBizImpl2 implements UserBiz{
@Override
public void list() {
System.out.println("查询用户数据...通过注册的时间点排序...");
}
}
测试:
package com.ycx.ioc.demo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ycx.web.UserAction;
public class Demo1 {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
UserAction userAction = (UserAction)context.getBean("userAction");
userAction.list();
}
}
打印结果:
因此,Spring只需要修改配置就好了(以前手动创建对象,Spring可自动创建对象):
spring-context.xml:
再测试:
package com.ycx.ioc.demo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ycx.web.OrderAction;
import com.ycx.web.UserAction;
/**
* 1、对Spring框架的配置进行建模,建模之后,spring-context.xml中所有的javabean信息都会加载进Spring 容器的上下文
* 2、上下文中包含了spring-context.xml 所有对象
* @author 杨总
*
*IOC的特点(什么叫控制反转):
* 指的是将创建对象的权利反转给Spring容器来完成
*
*/
public class Demo1 {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
UserAction userAction = (UserAction)context.getBean("userAction");
userAction.list();
OrderAction orderAction = (OrderAction)context.getBean("orderAction");
orderAction.list();
}
}
IOC的特点(什么叫控制反转):
指的是将创建对象的权利反转给Spring容器来完成
如果把OrderAction内的get和set方法注释掉,再测试,会报错:
所以我们来需要了解依赖注入的三种方式。
依赖注入的三种方式:
1、set注入——在业务类中获取属性的set和get方法UserAction:
package com.ycx.web; import java.util.List; import com.ycx.biz.UserBiz; import com.ycx.biz.impl.UserBizImpl1; import com.ycx.biz.impl.UserBizImpl2; /** * 依赖注入的三种方式: * 1、set注入 * 2、构造注入 * 3、自动装配 * byName * byType * * @author 杨总 * */ public class UserAction { // private UserBiz userBiz=new UserBizImpl1(); private UserBiz userBiz; public UserBiz getUserBiz() { return userBiz; } public void setUserBiz(UserBiz userBiz) { this.userBiz = userBiz; } private String name; private int age; private List
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 getHobby() { return hobby; } public void setHobby(List hobby) { this.hobby = hobby; } public void list() { System.out.println(name); System.out.println(age); System.out.println(hobby); userBiz.list(); } } spring-context.xml:
唱歌 跳舞 乒乓球 Demo1:
package com.ycx.ioc.demo; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.ycx.web.OrderAction; import com.ycx.web.UserAction; /** * 1、对Spring框架的配置进行建模,建模之后,spring-context.xml中所有的javabean信息都会加载进Spring 容器的上下文 * 2、上下文中包含了spring-context.xml 所有对象 * @author 杨总 * *IOC的特点(什么叫控制反转): * 指的是将创建对象的权利反转给Spring容器来完成 * */ public class Demo1 { @SuppressWarnings("resource") public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml"); UserAction userAction = (UserAction) context.getBean("userAction"); userAction.list(); OrderAction orderAction = (OrderAction)context.getBean("orderAction"); orderAction.list(); } }
在Demo1中运行,
打印结果如下:
2、构造注入——在业务类中回去属性的构造方法
OrderAction :
package com.ycx.web; import java.util.List; import com.ycx.biz.UserBiz; import com.ycx.biz.impl.UserBizImpl1; import com.ycx.biz.impl.UserBizImpl2; public class OrderAction { // private UserBiz userBiz=new UserBizImpl1(); private UserBiz userBiz; public UserBiz getUserBiz() { return userBiz; } public void setUserBiz(UserBiz userBiz) { this.userBiz = userBiz; } private String name; private int age; private List
hobby; public OrderAction(String name, int age, List hobby) { super(); this.name = name; this.age = age; this.hobby = hobby; } public OrderAction() { super(); } public void list() { System.out.println(name); System.out.println(age); System.out.println(hobby); userBiz.list(); } } spring-context.xml:
唱歌 跳舞 乒乓球 然后在Demo1运行:
3、自动装配
① byName——是Spring管理的bean对象的id进行查找,如果找不到则注入失败,反之成功
②byType——是Spring管理的bean对象接口实现类进行查找,如果没有或两个以上,则注入失败,反之成功。
package com.ycx.ioc.demo;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ycx.web.UserAction;
@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();
super.service(req, res);
}
}
package com.ycx.ioc.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ycx.web.UserAction;
public class SpringLoadListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("初始化......");
// 拿到Spring的上下文
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
// 将Spring上文保存到Tomcat上下文中
ServletContext servletContext=sce.getServletContext();
servletContext.setAttribute("springContext", context);
}
}
Archetype Created Web Application
com.ycx.ioc.listener.SpringLoadListener
运行:
Archetype Created Web Application
springConfigLocation
/applicationContext.xml
com.ycx.ioc.listener.SpringLoadListener
package com.ycx.ioc.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ycx.web.UserAction;
public class SpringLoadListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("初始化......");
ServletContext servletContext=sce.getServletContext();
String springConfigLocation = servletContext.getInitParameter("springConfigLocation");
System.out.println(springConfigLocation+"......");
// 拿到Spring的上下文
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
// 将Spring上文保存到Tomcat上下文中
servletContext.setAttribute("springContext", context);
}
}
容器框架 用来整合其他的第三方框架
有两大核心组件:IOC和aop
特点:依赖注入、控制反转
控制反转:将创建对象的权利,由程序员手动new对象的权利交给Spring容器
优点:便于维护,拥抱变化
set注入
构造注入
自动装配
byName:根据bean的id在Spring的上下文进行寻找
byType:根据属性接口在Spring上下文找对应的接口实现类
监听器 初始化
优化