1.spring简介
1.1含义
Spring是一个开源框架,它由Rod Johnson创建。
spring ==>"春天",意味着javaIT迎来了 “春天” ,
spring无处不在,自从这个框架推出以来,就一直被程序员们喜爱,受欢迎,很多项目中广 泛运用,Spring还拥有科技界所有知名人士的贡献,包括阿里巴巴,亚马逊,谷歌,Microsoft等
简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
Spring的核心loc和AOP:
1.2优点
Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。
然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
范围:任何Java应用-
2,Spring之IOC详解
2.1,控制反转是什么
控制反转(IoC=Inversion of Control)IoC,用白话来讲,就是由容器控制程序之间的(依赖)关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:(依赖)控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。 IoC还有一个另外的名字:“依赖注入 (DI=Dependency Injection)” ,即由容器动态的将某种依赖关系注入到组件之中 ,就是将以前由程序员实例化对象/赋值的工作交给了spring处理。
2.2,控制反转案例
场景演练:客户需求,更改个人信息 ,但是现在需要在这个基础之上做迭代 可以上传头像,并且提高性能
1.如果客户说“有些地方需要上传头像功能,有些地方不需要上传头像功能呢”
package com.sy.ioc.service.impl; import com.sy.ioc.service.UserService; /** * @author 谌艳 * @site www.shenyan.com * @create 2023-08-16 14:28 * 客户的需求: * 需求:客户登录后需要具备更改个人信息的功能 * * 场景一: * 客户要求,在新增的需求上做迭代,如上传头像 * 场景二: *客户要求,再新增的需求上做优化,提高性能,如使用多线程 * */ public class UserServiceImp implements UserService { public void update(){ System.out.println("更改个人用户信息"); // 添加上传头像的功能代码 System.out.println("上传头像的功能"); } }
2.我们就可以建立两个类,一个类有上传头像功能,一个没有,到时候在后台调用的时候,调用不同的类就行,
package com.sy.ioc.service.impl; import com.sy.ioc.service.UserService; /** * @author 谌艳 * @site www.shenyan.com * @create 2023-08-16 14:28 * 客户的需求: * 需求:客户登录后需要具备更改个人信息的功能 * * 场景一: * 客户要求,在新增的需求上做迭代,如上传头像 * 场景二: *客户要求,再新增的需求上做优化,提高性能,如使用多线程 * */ public class UserServiceImpl implements UserService { public void update(){ System.out.println("更改个人用户信息"); // 添加上传头像的功能代码 // System.out.println("上传头像的功能"); } }
package com.sy.ioc.service.impl; import com.sy.ioc.service.UserService; /** * @author 谌艳 * @site www.shenyan.com * @create 2023-08-16 14:28 * 客户的需求: * 需求:客户登录后需要具备更改个人信息的功能 * * 场景一: * 客户要求,在新增的需求上做迭代,如上传头像 * 场景二: *客户要求,再新增的需求上做优化,提高性能,如使用多线程 * */ public class UserServiceImp implements UserService { public void update(){ System.out.println("更改个人用户信息"); // 添加上传头像的功能代码 System.out.println("上传头像的功能"); } }
用IoC来运用一下,将实例化对象的这一步交给spring来帮助我们完成。
首先,我们要先建一个spring的配置文件
接下来我们将UserService看作一个属性,给它写set,get方法
然后编辑xml.文件,凡是在spring配置文件中配置,那么该类JavaBean就交给了spring容器管理我们在里面像下面,web层和Impl层,写出路径,并且给它命一个ID 将impl注入该类中,那么该类就用了impl中的方法
<?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核心配置文件 spring-conetxt.xml中配置,那么该类JavaBean就交给spring容器--> <bean class="com.sy.ioc.web.UserAction" id="userAction"> <!-- 将impl注入User Action--> <property name="userService" ref="userService"></property> </bean> <bean class="com.sy.ioc.web.GoodsAction" id="goodAction"> <!-- 将impl注入User Action--> <property name="userService" ref="userService1"></property> </bean> <bean class="com.sy.ioc.service.impl.UserServiceImp" id="userService"></bean> <bean class="com.sy.ioc.service.impl.UserServiceImpl" id="userService1"></bean> </beans>
2.1.3案例前台测试
package com.sy.ioc.demo; import com.sy.ioc.web.GoodsAction; import com.sy.ioc.web.UserAction; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author 谌艳 * @site www.shenyan.com * @create 2023-08-16 16:37 */ public class Demo1 { public static void main(String[] args){ // 加载获取spring配置文件及上下文对象,可以获取 ClassPathXmlApplicationContext context= new ClassPathXmlApplicationContext("/spring-context.xml"); // 通过id获取 UserAction userAction= (UserAction) context.getBean("userAction"); userAction.update(); System.out.println("========================================="); GoodsAction goodsAction =(GoodsAction) context.getBean("goodAction"); goodsAction.update(); } }
3、IoC的三种注入方式
3.1 构造方法注入
构造函数注入(Constructor Injection):通过构造函数来注入依赖对象。在类的构造函数中声明依赖对象的参数,并在容器中配置时提供相应的依赖对象。当创建对象实例时,容器会自动将依赖对象传递给构造函数,完成依赖注入。
先定义属性,其次提供有参,无参构造方法,一样提供获取属性的方法
package com.sy.ioc.web; import com.sy.ioc.service.UserService; import java.util.List; /** * @author 谌艳 * @site www.shenyan.com * @create 2023-08-16 14:47 * * 程序员手动实列化对象的弊端 * 1.一旦依赖的接口的实现需要大批量改动,迭代,维护成本极高 * 2.当接口的实现类不统一,维护成本更高 */ public class UserAction { private UserService userService; // 将一个类看作一个属性 private String uname;//用户名字 private int age;//用户年龄 private List<String> hobby;//用户喜好 public UserService getUserService() { return userService; } public void setUserService(UserService userService) { this.userService = userService; } public UserAction(String uname, int age, List<String> hobby) { this.uname = uname; this.age = age; this.hobby = hobby; } public UserAction() { } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } 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; } public String update(){ userService.update(); return "list"; } }
最后再前台输入
package com.sy.ioc.demo; import com.sy.ioc.web.GoodsAction; import com.sy.ioc.web.UserAction; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author 谌艳 * @site www.shenyan.com * @create 2023-08-16 16:37 */ public class Demo1 { public static void main(String[] args){ // 加载获取spring配置文件及上下文对象,可以获取 ClassPathXmlApplicationContext context= new ClassPathXmlApplicationContext("/spring-context.xml"); // 通过id获取 UserAction userAction= (UserAction) context.getBean("userAction"); userAction.update(); System.out.println("========================================="); GoodsAction goodsAction =(GoodsAction) context.getBean("goodAction"); goodsAction.update(); System.out.println("==============================================="); goodsAction.pros(); System.out.println("============================================="); } }
结果:
3.2 setter方法注入
Setter方法注入(Setter Injection):通过setter方法来注入依赖对象。在类中定义相应的setter方法,并在容器中配置时使用相应的属性或标签指定依赖对象。当创建对象实例后,容器会调用相应的setter方法,将依赖对象注入到对象中。
先创建属性,提供get,set方法,写一个方法调用这些属性
package com.sy.ioc.web; import com.sy.ioc.service.UserService; import java.util.List; /** * @author 谌艳 * @site www.shenyan.com * @create 2023-08-16 15:00 */ public class GoodsAction { private UserService userService; // 将一个类看作一个属性 private String gname;//商品名字 private int age;//保质期 private List<String> type;//种类 public UserService getUserService() { return userService; } public void setUserService(UserService userService) { this.userService = userService; } public String getGname() { return gname; } public void setGname(String gname) { this.gname = gname; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public List<String> getType() { return type; } public void setType(List<String> type) { this.type = type; } public String update(){//调用方法 userService.update(); return "list"; } public void pros(){//获取属性 System.out.println(this.gname); System.out.println(this.age); System.out.println(this.type); } }
然后再配置文件中,注入这些属性
然后再到前台调用:
package com.sy.ioc.demo; import com.sy.ioc.web.GoodsAction; import com.sy.ioc.web.UserAction; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author 谌艳 * @site www.shenyan.com * @create 2023-08-16 16:37 */ public class Demo1 { public static void main(String[] args){ // 加载获取spring配置文件及上下文对象,可以获取 ClassPathXmlApplicationContext context= new ClassPathXmlApplicationContext("/spring-context.xml"); // 通过id获取 UserAction userAction= (UserAction) context.getBean("userAction"); userAction.update(); System.out.println("========================================="); GoodsAction goodsAction =(GoodsAction) context.getBean("goodAction"); goodsAction.update(); System.out.println("==============================================="); goodsAction.pros(); System.out.println("============================================="); } }
结果:
3.3 接口注入(自动装配)===用的最多,最方便
有两种方式:byName 和byType
byName:javabean会根据属性名在spring配置文件上下文中根据spring上下文中的bean ID进行查找,只要有就会自动注入
byType:javabean会根据属性名对应的接口类型在spring配置文件上下文中根据spring上下文是否有该接口类型的实现类进行注入,如果找到两个及以上,那么spring配置文件会包错
4.spring与web容器的整合
我们每一个请求如果都要拿到UserActiob都需要建模一次的话,非常消耗性能,希望只建模一次,然后每一个请求都可以获取到spring上下文,那么就有监听器可以做到,将spring放入tomcat上下文
创建一个监听器将spring放入tomcat上下文
当用户请求的时候,获取spring上下文对象
运行结果: