转载请标明出处:https://blog.csdn.net/men_ma/article/details/106847165.
本文出自 不怕报错 就怕不报错的小猿猿 的博客
这里写目录标题
前言
此篇博客与上篇博客息息相关,博主怕文章幅度太长,续接上篇博客,现附上博客链接,不然你看这篇博客可能有点懵
链接: 什么是spring?SSH指的又是什么?spring之ioc(控制反转)如何理解?及IOC的具体实现在哪?.
1.IOC的注入方式及各类类型
1.1 set注入(一定要get/set方法赋值)
1.1.1 基本类型与string
1.1.2 数组
1.1.3 自定义类型
1.1.4 spring-context中配置set注入用property标签
<!--*********************************IOC********************************* -->
<bean class="com.xiaoqing.ioc.biz.UserBizImpl1" id="userBiz"></bean>
<bean class="com.xiaoqing.ioc.web.UserAction" id="xxx">
<!--set注入用property标签 -->
<property name="userBiz" ref="userBiz"></property>
<property name="uname" value="zs"></property>
<property name="age" value="22"></property>
<property name="hobby">
<list>
<value>篮球</value>
<value>rap</value>
<value>广场舞</value>
</list>
</property>
</bean>
1.1.5 写一个方法测试set注入的值都注入成功没
public void test1() {
System.out.println(this.uname);
System.out.println(this.age);
System.out.println(this.hobby);
}
public static void main(String[] args) {
ApplicationContext springContext = new ClassPathXmlApplicationContext("/spring-context.xml");
// 得到id为xxx的bean
UserAction userAction =(UserAction)springContext.getBean("xxx");
userAction.test1();
}
测试结果:
1.2 构造器注入(当没有set/get方法时)
把set/get方法去掉时,创建构造方法,例如:
修改spring-context配置文件:
<!--*********************************IOC********************************* -->
<bean class="com.xiaoqing.ioc.biz.UserBizImpl1" id="userBiz"></bean>
<bean class="com.xiaoqing.ioc.web.UserAction" id="xxx">
<!--set注入用property标签 -->
<property name="userBiz" ref="userBiz"></property>
<!-- 构造注入 用constructor-arg标签 -->
<constructor-arg name="uname" value="zs"></constructor-arg>
<constructor-arg name="age" value="22"></constructor-arg>
<property name="hobby">
<list>
<value>篮球</value>
<value>rap</value>
<value>广场舞</value>
</list>
</property>
</bean>
测试结果:同上测试代码
1.3 自动装配(用的最多的)
自动装配
spring4之后出现的
byType:根据配置的Bean中的接口,在spring的上下文中寻找对应的实现类
byName:根据配置的Bean对象中的接口(属性)名字,在spring的上下文中寻找对应的实现类(公司常用)
spring -context文件:注意( <property name="userBiz" ref="userBiz"></property>
)在这里没用了
<bean class="com.xiaoqing.ioc.biz.UserBizImpl2" id="userBiz"></bean>
<bean class="com.xiaoqing.ioc.web.UserAction" id="xxx">
</bean>
<bean class="com.xiaoqing.ioc.web.OrderAction" id="ttt">
</bean>
userBiz这个属性一点要在action中set/get方法,才能自动装配进去,流程:id=“userBiz”(user的实现类)------->UserAction(中的属性userBiz)-------------->会把userBiz属性自动装配到某个接口中去
测试代码:
public static void main(String[] args) {
ApplicationContext springContext = new ClassPathXmlApplicationContext("/spring-context.xml");
// 得到id为xxx的bean
UserAction userAction =(UserAction)springContext.getBean("xxx");
// 得到id为ttt的bean
OrderAction orderAction =(OrderAction)springContext.getBean("ttt");
userAction.upload();
orderAction.upload();
}
测试结果:
对于注入方式的代码,都在同上,在这里就不重复copy啦,其他代码不变,要修改的地方我会标明
博客白话:在自动装配中,我们有时会多个action去实现调用多个接口,在上篇博客中博主用了两个action 及UserAction和orderAction,他们都调用了UserBiz接口,我们不用写重复的property属性了
2.spring与Tomcat整合
为什么要利用Tomcat整合呢,在这里用博主的白话来说,当我们在网页上发送一个http的请求时,我们要访问到后台的spring-context.xml中的Javabean配置中访问后台,要通过一个servlet或者子控制器处理,处理的时候我们要在对应的处理业务逻辑里面访问到指定的Javabean(根据bean的id),我们不可能每次都要去建模,如果不用Tomcat的话只有通过建模才能拿到Javabean(UserAction userAction =(UserAction)springContext.getBean(“xxx”)),我们不可能每次都要建模,建模也是非常消耗性能的,所以我们现在的处理方式就是利用Tomcat整合,如下步骤:
2.1 用到的目录结构
2.2 spring作为管理整个工程中的的所有的Javabean,那么如何在用户发送请求的时候能够访问到指定的Javabean呢?
处理方式:
在监听器中 将spring的上下文交给Tomcat的上下文中进行管理(意味着Tomcat能够拿到spring的上下文)
-
思路:每一次浏览器请求---->拿到request---->servletContext(Tomcat上下文)---->springContext(spring上下文) ---->任意的Javabean
2.3 web.xml配置
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>springXmlLocation</param-name>
<param-value>/spring-other.xml</param-value>
</context-param>
</web-app>
2.4 SpringLoaderListener.java (一定要实现ServletContextListener接口)注释比较详细,也要注意头部注解
/**
*
* spring作为管理整个工程中的的所有的Javabean,那么如何在用户发送请求的时候能够访问到指定的Javabean呢
* 处理方式:
* 在监听器中 将spring的上下文交给Tomcat的上下文中进行管理
* 浏览器---->request---->servletContext---->springContext ---->任意的Javabean
*
*
* @author 晴sister
* 2020年8月5日19:55:07
*
*/
@WebListener //注解配置web监听器(相当于<listener></listener>)
public class SpringLoaderListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Tomcat一启动就触发了。。。。");
// 获取到Tomcat的上下文
ServletContext tomcatContext = sce.getServletContext();
// 从web.xml的监听器参数拿到的
String springXmlLocation=tomcatContext.getInitParameter("springXmlLocation");
System.out.println("spring 的上下文配置文件:"+springXmlLocation);
ApplicationContext springContext=null;
// 如果web.xml中没有配置springXmlLocation或者等于空
if(springXmlLocation==null||"".equals(springXmlLocation)) {
// 获取到spring的上下文
springContext=new ClassPathXmlApplicationContext("/spring-context.xml");
}else {
springContext=new ClassPathXmlApplicationContext(springXmlLocation);
}
tomcatContext.setAttribute("spring_key", springContext);
}
}
2.5 利用servlet来处理用户请求(UserServlet.java)注意头部注解
@WebServlet("/user")//注解配置servlet
public class UserServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("处理用户请求");
// 拿到Tomcat上下文
ServletContext tomcatContext = req.getServletContext();
// 通过attribute拿到spring上下文
ApplicationContext springContext = (ApplicationContext)tomcatContext.getAttribute("spring_key");
// 根据bean的id拿到action
UserAction userAction =(UserAction)springContext.getBean("xxx");
userAction.upload();
}
}
运行效果: