12. web 项目使用容器对象

空~2022年9月6日
  • Spring
大约 4 分钟

12. web 项目使用容器对象

以前做的是 javase 项目有 main 方法的, 执行代码是执行 main 方法的, 在 main 里面创建的容器对象.

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

web 项目是在 tomcat 服务器上运行的 tomcat 一起动,项目一直运行的

  • 需求:

web 项目中容器对象只需要创建一次, 把容器对象放入到全局作用域 ServletContext 中

  • 怎么实现:

使用监听器 当全局作用域对象被创建时 创建容器 存入 ServletContext

  • 监听器作用:
  1. 创建容器对象,执行 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  2. 把容器对象放入到 ServletContext, ServletContext.setAttribute(key,ctx)
  3. 监听器可以自己创建,也可以使用框架中提供好的 ContextLoaderListener

private WebApplicationContext context

public interface WebApplicationContext extends ApplicationContext

ApplicationContext: javase 项目中使用的容器对象

WebApplicationContext: web 项目中的使用的容器对象

把创建的容器对象,放入到全局作用域:

ervletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

key: WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE

value: this.context

环境搭建

controller 层

public class RegisterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

        String strId = request.getParameter("id");
        String strName = request.getParameter("name");
        String strEmail = request.getParameter("email");
        String strAge = request.getParameter("age");

        // 创建spring的容器对象
        // String config= "spring.xml";
        // ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
        WebApplicationContext ctx = null;
        // 获取ServletContext中的容器对象,创建好的容器对象,拿来就用
        /*String key =  WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;
    Object attr  = getServletContext().getAttribute(key);
    if( attr != null){
        ctx = (WebApplicationContext)attr;
    }*/

        // 使用框架中的方法,获取容器对象
        ServletContext sc = getServletContext();
        ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
        System.out.println("容器对象的信息========" + ctx);

        // 获取service
        StudentService service = (StudentService) ctx.getBean("studentService");
        Student student = new Student();
        student.setId(Integer.parseInt(strId));
        student.setName(strName);
        student.setEmail(strEmail);
        student.setAge(Integer.valueOf(strAge));
        service.addStudent(student);

        // 给一个页面
        request.getRequestDispatcher("/result.jsp").forward(request, response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {}
}

dao 层

public interface OrderDao {

    int insertStudent(Student student);

    List<Student> selectStudents();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjpowernode.dao.OrderDao">

  <insert id="insertStudent">
    insert into mybatis.student
    values (#{id}, #{name}, #{email}, #{age})
  </insert>

  <select id="selectStudents" resultType="com.bjpowernode.domain.Student">
    select id, name, email, age
    from mybatis.student
    order by id desc
  </select>
</mapper>
public interface StudentDao {

    int insertStudent(Student student);

    List<Student> selectStudents();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjpowernode.dao.StudentDao">

  <insert id="insertStudent">
    insert into mybatis.student(id, name,  age, email)
    values (#{id}, #{name}, #{age}, #{email})
  </insert>

  <select id="selectStudents" resultType="Student">
    select id, name, email, age
    from mybatis.student
    order by id desc
  </select>
</mapper>

实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    // 属性名和列名一样
    private Integer id;
    private String name;
    private String email;
    private Integer age;
}

service 层

public interface StudentService {

    int addStudent(Student student);

    List<Student> queryStudents();
}
public class StudentServiceImpl implements StudentService {

    // 引用类型
    private StudentDao studentDao;

    // 使用set注入,赋值
    public void setStudentDao(StudentDao studentDao) {
        this.studentDao = studentDao;
    }

    @Override
    public int addStudent(Student student) {
        int nums = studentDao.insertStudent(student);
        return nums;
    }

    @Override
    public List<Student> queryStudents() {
        List<Student> students = studentDao.selectStudents();
        return students;
    }
}

配置文件

jdbc.properties

jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.passwd=root
jdbc.max=30

mybatis.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

  <!--设置别名-->
  <typeAliases>
    <!--name:实体类所在的包名
            表示com.bjpowernode.domain包中的列名就是别名
            你可以使用Student表示com.bjpowenrode.domain.Student
        -->
    <package name="com.bjpowernode.domain"/>
  </typeAliases>


  <!-- sql mapper(sql映射文件)的位置-->
  <mappers>
    <!--
          name: 是包名, 这个包中的所有mapper.xml一次都能加载
        -->
    <package name="com.bjpowernode.dao"/>
  </mappers>
</configuration>

spring.xml

<?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: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/context https://www.springframework.org/schema/context/spring-context.xsd">

  <!--
       把数据库的配置信息,写在一个独立的文件,编译修改数据库的配置内容
       spring知道jdbc.properties文件的位置
    -->
  <context:property-placeholder location="classpath:jdbc.properties"/>

  <!--声明数据源DataSource, 作用是连接数据库的-->
  <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource"
        init-method="init" destroy-method="close">
    <!--set注入给DruidDataSource提供连接数据库信息 -->
    <!--    使用属性配置文件中的数据,语法 ${key} -->
    <property name="url" value="${jdbc.url}"/><!--setUrl()-->
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.passwd}"/>
    <property name="maxActive" value="${jdbc.max}"/>
  </bean>

  <!--声明的是mybatis中提供的SqlSessionFactoryBean类,这个类内部创建SqlSessionFactory的
        SqlSessionFactory  sqlSessionFactory = new ..
    -->
  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!--set注入,把数据库连接池付给了dataSource属性-->
    <property name="dataSource" ref="myDataSource"/>
    <!--mybatis主配置文件的位置
           configLocation属性是Resource类型,读取配置文件
           它的赋值,使用value,指定文件的路径,使用classpath:表示文件的位置
        -->
    <property name="configLocation" value="classpath:mybatis.xml"/>
  </bean>

  <!--创建dao对象,使用SqlSession的getMapper(StudentDao.class)
        MapperScannerConfigurer:在内部调用getMapper()生成每个dao接口的代理对象

    -->
  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--指定SqlSessionFactory对象的id-->
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    <!--指定包名, 包名是dao接口所在的包名
            MapperScannerConfigurer会扫描这个包中的所有接口,把每个接口都执行
            一次getMapper()方法,得到每个接口的dao对象
            创建好的dao对象放入到spring的容器中的 dao对象的默认名称是 接口名首字母小写
        -->
    <property name="basePackage" value="com.bjpowernode.dao"/>
  </bean>

  <!--声明service-->
  <bean id="studentService" class="com.bjpowernode.service.impl.StudentServiceImpl">
    <property name="studentDao" ref="studentDao"/>
  </bean>
</beans>

响应页面

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
  <html>
    <head>
      <title>Title</title>
    </head>
    <body>
      <p>注册学生</p>
      <form action="reg" method="post">
        <table>
          <tr>
            <td>id</td>
            <td><input type="text" name="id"></td>
          </tr>
          <tr>
            <td>姓名: </td>
            <td><input type="text" name="name"></td>
          </tr>
          <tr>
            <td>email:</td>
            <td><input type="text" name="email"></td>
          </tr>
          <tr>
            <td>年龄: </td>
            <td><input type="text" name="age"></td>
          </tr>
          <tr>
            <td></td>
            <td><input type="submit" value="注册学生"></td>
          </tr>
        </table>
      </form>
    </body>
  </html>

result.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>Title</title>
</head>
<body>
  result.jsp 注册成功
</body>
</html>