- spring简介
- spring ioc容器的特点
- spring注入方式
- spring上下文与tomcat整合
1.spring简介
1. 什么是spring,它能够做什么?
Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。
Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。
然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
范围:任何Java应用
简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
2.spring ioc容器的特点
2. 什么是控制反转(或依赖注入)
控制反转(IoC=Inversion of Control)IoC,用白话来讲,就是由容器控制程序之间的(依赖)关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:(依赖)控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。
IoC还有一个另外的名字:“依赖注入 (DI=Dependency Injection)” ,即由容器动态的将某种依赖关系注入到组件之中
案例:实现Spring的IoC
IOC/DI
将以前由程序员实例化对象/赋值的工作交给了spring处理
//pom.xml <?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <parent> <artifactId>ideamaven</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>Spring</artifactId> <packaging>war</packaging> <name>Spring Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</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>Spring</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build> </project>
package com.zlj.ioc.service; /** * @author zlj * @create 2023-08-15 16:46 */ public interface UserService { public void update(); }
package com.zlj.ioc.service; /** * @author zlj * @create 2023-08-15 16:46 * * 客户的需求: * 需求:客户登陆后需要具备更改个人信息的功能 * * 场景1: * 客户要求,在新增的需求上做迭代版本,如头像上传 * * 场景2: * 客户需求,在新增的需求上做优化,提升性能,如多线程 * * * */ public class UserServiceImp implements UserService{ public void update(){ System.out.println("更改个人用户信息"); // 添加上传头像的功能代码 // System.out.println("上传头像功能"); } }
package com.zlj.ioc.service; /** * @author zlj * @create 2023-08-15 16:56 */ public class UserServiceImp2 implements UserService{ public void update(){ System.out.println("更改个人用户信息"); // 添加上传头像的功能代码 System.out.println("上传头像功能"); } }
package com.zlj.ioc.web; import com.zlj.ioc.service.UserService; /** * @author zlj * @create 2023-08-15 21:20 */ public class GoodsAction { private UserService userservice; public UserService getUserservice() { return userservice; } public void setUserservice(UserService userservice) { this.userservice = userservice; } public String update(){ userservice.update(); return "list"; } }
package com.zlj.ioc.web; import com.zlj.ioc.service.UserService; /** * @author zlj * @create 2023-08-15 17:07 * <p> * 程序员手动实例化对象的弊端 * 1.一旦依的接口的实现需要大批量改动,迭代,维护的成本极高 * 2.当接口的实现类不统一,维护成本更高 */ public class UserAction { private UserService userservice; public UserService getUserservice() { return userservice; } public void setUserservice(UserService userservice) { this.userservice = userservice; } public String update() { userservice.update(); return "list"; } }
<?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"> <!--凡是在sprng配置文件spring-context.xml中配置,那么该类javabean就交给了spring容器管理--> <bean class="com.zlj.ioc.web.UserAction" id="userAction"> <property name="userservice" ref="userservice"></property> </bean> <bean class="com.zlj.ioc.web.GoodsAction" id="goodsAction"> <property name="userservice" ref="UserServiceImp"></property> </bean> <bean class="com.zlj.ioc.service.UserServiceImp2" id="userservice"></bean> <bean class="com.zlj.ioc.service.UserServiceImp" id="UserServiceImp"></bean> </beans>
package com.zlj.ioc.demo; import com.zlj.ioc.web.GoodsAction; import com.zlj.ioc.web.UserAction; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author zlj * @create 2023-08-15 22:26 */ public class demo1 { public static void main(String[] args) { //加载spring核心配置文件(建模),获取spring的上下文对象,上下文对象中可以获取任何Javabean对象 ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("/spring-context.xml"); UserAction userAction= (UserAction) context.getBean("userAction"); userAction.update(); GoodsAction goodsAction = (GoodsAction) context.getBean("goodsAction"); goodsAction.update(); } }
3.spring注入方式
1.第一种注入方式( set方法属性注入,GoodsAction):
package com.zlj.ioc.web; import com.zlj.ioc.service.UserService; import java.util.List; /** * @author zlj * @create 2023-08-15 21:20 * spring的注入方式 * */ public class GoodsAction { private UserService userservice; private String gname; private int age;//保质期 private List<String> people;//商品的使用人群 public List<String> getPeople() { return people; } public void setPeople(List<String> people) { this.people = people; } 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 UserService getUserservice() { return userservice; } public void setUserservice(UserService userservice) { this.userservice = userservice; } public String update(){ userservice.update(); return "list"; } public void pros(){ System.out.println(this.gname); System.out.println(this.age); System.out.println(this.people); } }
<?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"> <!--凡是在sprng配置文件spring-context.xml中配置,那么该类javabean就交给了spring容器管理--> <bean class="com.zlj.ioc.web.UserAction" id="userAction"> <property name="userservice" ref="userservice"></property> </bean> <bean class="com.zlj.ioc.web.GoodsAction" id="goodsAction"> <property name="userservice" ref="UserServiceImp"></property> <property name="gname" value="鱼"></property> <property name="age" value="1"></property> <property name="people"> <list> <value>比目鱼</value> <value>金鱼</value> </list> </property> </bean> <bean class="com.zlj.ioc.service.UserServiceImp2" id="userservice"></bean> <bean class="com.zlj.ioc.service.UserServiceImp" id="UserServiceImp"></bean> </beans>
2.第二种注入方式(构造注入,UserAction):
package com.zlj.ioc.web; import com.zlj.ioc.service.UserService; import java.util.List; /** * @author zlj * @create 2023-08-15 17:07 * <p> * 程序员手动实例化对象的弊端 * 1.一旦依的接口的实现需要大批量改动,迭代,维护的成本极高 * 2.当接口的实现类不统一,维护成本更高 */ public class UserAction { private UserService userservice; private String uname; private int age; private List<String> hobby; public UserAction() { } public UserAction(String uname, int age, List<String> hobby) { this.uname = uname; this.age = age; this.hobby = hobby; } public List<String> getHobby() { return hobby; } public void setHobby(List<String> hobby) { this.hobby = hobby; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public UserService getUserservice() { return userservice; } public void setUserservice(UserService userservice) { this.userservice = userservice; } public String update() { userservice.update(); return "list"; } public void pros(){ System.out.println(this.uname); System.out.println(this.age); System.out.println(this.hobby); } }
<?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"> <!--凡是在sprng配置文件spring-context.xml中配置,那么该类javabean就交给了spring容器管理--> <bean class="com.zlj.ioc.web.UserAction" id="userAction"> <property name="userservice" ref="userservice"></property> <constructor-arg name="uname" value="小白"></constructor-arg> <constructor-arg name="age" value="18"></constructor-arg> <constructor-arg name="hobby"> <list> <value>哈士奇</value> <value>狸花猫</value> <value>猎犬</value> </list> </constructor-arg> </bean> <bean class="com.zlj.ioc.web.GoodsAction" id="goodsAction"> <property name="userservice" ref="UserServiceImp"></property> <property name="gname" value="鱼"></property> <property name="age" value="1"></property> <property name="people"> <list> <value>比目鱼</value> <value>金鱼</value> </list> </property> </bean> <bean class="com.zlj.ioc.service.UserServiceImp2" id="userservice"></bean> <bean class="com.zlj.ioc.service.UserServiceImp" id="UserServiceImp"></bean> </beans>
package com.zlj.ioc.demo; import com.zlj.ioc.web.GoodsAction; import com.zlj.ioc.web.UserAction; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author zlj * @create 2023-08-15 22:26 */ public class demo1 { public static void main(String[] args) { //加载spring核心配置文件(建模),获取spring的上下文对象,上下文对象中可以获取任何Javabean对象 ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("/spring-context.xml"); UserAction userAction= (UserAction) context.getBean("userAction"); userAction.update(); System.out.println("================================================================="); userAction.pros(); GoodsAction goodsAction = (GoodsAction) context.getBean("goodsAction"); goodsAction.update(); System.out.println("==============================================================="); goodsAction.pros(); } }
3.第三种引用方式(自动装配中的byName和byType):
byName:JavaBean会根据属性名在spring是根据spring上下文中进行查找
是根据spring上下文中的bean的id进行查,只要有,就会自动注入
byType:JavaBean会根据属性名对应的接口类型,在spring上下文中进行查找
是根据spring上下文中是否有该接口类型的实现类进行匹配,只要有,就会自动注入
注意:如果找到两个及以上,那么spring会报错
//byName <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" default-autowire="byName" 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"> <!--凡是在sprng配置文件spring-context.xml中配置,那么该类javabean就交给了spring容器管理--> <bean class="com.zlj.ioc.web.UserAction" id="userAction"> <!-- <property name="userservice" ref="userservice"></property>--> <!-- <constructor-arg name="uname" value="小白"></constructor-arg>--> <!-- <constructor-arg name="age" value="18"></constructor-arg>--> <!-- <constructor-arg name="hobby">--> <!-- <list>--> <!-- <value>哈士奇</value>--> <!-- <value>狸花猫</value>--> <!-- <value>猎犬</value>--> <!-- </list>--> <!-- </constructor-arg>--> </bean> <bean class="com.zlj.ioc.web.GoodsAction" id="goodsAction"> <!-- <property name="userservice" ref="UserServiceImp"></property>--> <!-- <property name="gname" value="鱼"></property>--> <!-- <property name="age" value="1"></property>--> <!-- <property name="people">--> <!-- <list>--> <!-- <value>比目鱼</value>--> <!-- <value>金鱼</value>--> <!-- </list>--> <!-- </property>--> </bean> <bean class="com.zlj.ioc.service.UserServiceImp2" id="userservice"></bean> <bean class="com.zlj.ioc.service.UserServiceImp" id="UserServiceImp"></bean> </beans>
//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"> <!--凡是在sprng配置文件spring-context.xml中配置,那么该类javabean就交给了spring容器管理--> <bean class="com.zlj.ioc.web.UserAction" id="userAction"> <!-- <property name="userservice" ref="userservice"></property>--> <!-- <constructor-arg name="uname" value="小白"></constructor-arg>--> <!-- <constructor-arg name="age" value="18"></constructor-arg>--> <!-- <constructor-arg name="hobby">--> <!-- <list>--> <!-- <value>哈士奇</value>--> <!-- <value>狸花猫</value>--> <!-- <value>猎犬</value>--> <!-- </list>--> <!-- </constructor-arg>--> </bean> <bean class="com.zlj.ioc.web.GoodsAction" id="goodsAction"> <!-- <property name="userservice" ref="UserServiceImp"></property>--> <!-- <property name="gname" value="鱼"></property>--> <!-- <property name="age" value="1"></property>--> <!-- <property name="people">--> <!-- <list>--> <!-- <value>比目鱼</value>--> <!-- <value>金鱼</value>--> <!-- </list>--> <!-- </property>--> </bean> <!-- <bean class="com.zlj.ioc.service.UserServiceImp2" id="userservice"></bean>--> <bean class="com.zlj.ioc.service.UserServiceImp" id="UserServiceImp"></bean> </beans>
4.spring上下文与tomcat整合(监听器)
package com.king.ioc.listener; import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; /** * @author zlj * @create 2023-08-16 3:05 */ @WebListener public class StringLoadListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("初始化:将spring上下文放入tomcat上下文"); // 将spring上下文放入tomcat上下文 ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("/spring-context.xml"); // 获取comcat上下文 ServletContext servletContext = sce.getServletContext(); servletContext.setAttribute("springContext",context); } }
package com.zlj.ioc.web; import com.zlj.ioc.service.UserService; import org.springframework.context.support.ClassPathXmlApplicationContext; 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; /** * @author zlj * @create 2023-08-16 3:14 */ @WebServlet("/userList") public class UserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //加载spring核心配置文件(建模),获取spring的上下文对象,上下文对象中可以获取任何Javabean对象 ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("/spring-context.xml"); UserService userserivce = (UserService) context.getBean("userservice"); System.out.println(userserivce); userserivce.update(); } }