当前位置: 首页 > news >正文

长春seo代理计费/谷歌优化怎么做

长春seo代理计费,谷歌优化怎么做,汕头个人建站模板,网站建设后台功能Spring注解开发 Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,它能够代替xml配置文件,可以简化配置,提高开发效率Spring注解根据出现时间分类 Spring原始注解&#xf…

Spring注解开发

  • Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,它能够代替xml配置文件,可以简化配置,提高开发效率
  • Spring注解根据出现时间分类
    • Spring原始注解:主要代替<bean>的配置
    • Spring新注解:Spring配置文件中有些配置是Spring原始注解无法替代的,此时就需要新注解,比如:
      • 非自定义的Bean的配置,比如Druid、Cp30的bean
      • 加载properties配置文件的配置:<context:property-placeholder location="classpath:jdbc.properties"/>
      • 组件扫描的配置:<context:component-scan base-package="at.guigu"></context:component-scan>
      • 引入其它配置文件的配置:<import resource="applicationContext-xxx.xml"/>
  • 注意
    • 使用注解开发时,需要在Spring配置文件中配置组件扫描
      • 作用:指定哪个包及其子包下的bean需要进行扫描,以便可以识别使用注解配置的类、字段和方法

Spring原始注解快速入门

  • 不使用注解开发时的代码截图如下(以setter方法注入为例)

    在这里插入图片描述

  • 使用注解开发的步骤

    • Step1: 在pom.xml文件中导入相应的坐标及插件:Spring坐标、Annotation坐标、Tomcat插件。pom.xml文件完整代码如下

      <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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>SpringDemo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>SpringAnno</artifactId><packaging>war</packaging><name>SpringAnno Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version></dependency><!--Annotation坐标--><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version></dependency></dependencies><build><finalName>SpringAnno</finalName><plugins><!-- Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build>
      </project>
      
    • Step2: 给对应的类添加注解

      • UserDaoImpl类代码如下

        package at.guigu.dao.impl;import at.guigu.dao.UserDao;
        import org.springframework.stereotype.Repository;// <bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"></bean>
        // 等同于@Component("userDaoImpl")
        @Repository("userDaoImpl")
        public class UserDaoImpl implements UserDao {public void save() {System.out.println("UserDao save running...");}
        }
        
      • BookServiceImpl类代码如下

        package at.guigu.service.impl;
        import at.guigu.dao.UserDao;
        import at.guigu.service.BookService;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.beans.factory.annotation.Qualifier;
        import org.springframework.stereotype.Service;//<bean id="bookServiceImpl" class="at.guigu.service.impl.BookServiceImpl"></bean>
        // 等同于@Component("bookServiceImpl")
        @Service("bookServiceImpl")
        public class BookServiceImpl implements BookService {// <property name="userDao" ref="userDaoImpl"/>@Autowired@Qualifier("userDaoImpl")private UserDao userDao;/*public void setUserDao(UserDao userDao) {this.userDao = userDao;}*/@Overridepublic void save() {System.out.println("BookService save...");userDao.save();}
        }
        
    • Step3: 在Spring配置文件中配置注解的组件扫描,Spring配置文件代码如下

      • 配置组件扫描需要在Spring配置文件中引入context命名空间和context约束路径然后使用context命名空间加载 properties 文件。Spring配置文件代码如下
        1. 命名空间:xmlns:context="http://www.springframework.org/schema/context"
        2. 约束路径:http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
      • 配置组件扫描代码:<context:component-scan base-package="at.guigu"></context:component-scan>
        • base-package:给定一个包,然后会自动扫描该包下的所有内容,以便可以识别使用注解配置的类、字段和方法
      <?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--配置注解的组件扫描--><context:component-scan base-package="at.guigu"></context:component-scan>
      </beans>
      
    • Step4: 测试类TestOne代码如下

      package at.guigu.web;import at.guigu.service.impl.BookServiceImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestOne {@Testpublic void test1() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      在这里插入图片描述

  • 使用注解开发的与使用配置文件进行依赖注入的对比图例如下

    在这里插入图片描述

Spring原始注解

原始注解解释
@Component使用在类上,用于实例化bean
@Controller使用在Web层的类上,用于实例化bean
@Service使用在Service层的类上,用于实例化bean
@Repository使用在Dao/Mapper层的类上,用于实例化bean
@Autowired使用在字段上,用于根据类型进行自动依赖注入
@Qualifier("beanId")必须与@Autowired一起使用,用于根据名称进行依赖注入,从而避免按类型自动装配时的歧义
@Resource(name = "beanId")相当于@Autowired+@Resource。它既可以按名称注入,也可以按类型注入。它的默认行为是按名称注入,如果找不到匹配的名称,再按类型注入。
@Value注入普通属性
@Scope使用在类上,标注bean的作用范围。默认为@Scope("singleton"):单例; @Scope("prototype"):多例
@PostConstruct使用在方法上,标注该方法是bean的初始化方法
@PreDestroy使用在方法上,标注该方法是bean的销毁方法
  • 注意

    • @Repository@Service@Controller以上三个注解能用@Component来代替

      • 因为这三个注解本质上都是 @Component 注解的扩展
    • 使用@Autowired@Qualifier("beanId")@Resource("beanId")这三个注解进行依赖注入时,可以省略不写setter方法

    • @Value用于替代value,即只能用于基本数据类型与字符串类型

    • @Scope不在进行测试,可自行测试

  • @Autowired@Qualifier注解详解

    • @Autowired是按照数据类型从Spring容器中进行自动匹配的。它会自动匹配对应引用类型的实现类的bean
    • @Qualifier注解必须与@Autowired一起配合使用。它是按照对应bean的id值从Spring容器中进行匹配的
    • 若只使用@Autowired,而不与@Qualifier配合使用时:使用@Autowired注解的引用数据类型对应的bean在Spring容器中只能有一个;反之则必须与@Qualifier联合使用
  • @Resource注解详解

    • @Resource相当于@Autowired+@Resource
    • @Resource(name = "beanId"):如果 beanId 属性被指定,首先按名称查找;如果没有指定 beanId,则按字段或属性名进行查找;如果没有找到匹配的名称,再按类型查找。
    • @Resource注解在代码中必须写为@Resource(name = "beanId")的形式,若不加上name=,则会报错
  • 只使用@Autowired的示例

    • 使用@Autowired注解的属性只存在一个对应实现类的bean

      在这里插入图片描述

    • 使用@Autowired注解的属性存在多个对应实现类的bean

      • 错误示例

      在这里插入图片描述

      • 正确示例:此时必须与@Qualifier联合使用

      @Autowired@Qualifier("beanId")联合使用

      在这里插入图片描述

      @Resource代替@Autowired+@Resource

      在这里插入图片描述

@Value注入普通属性

  • 简单形式的代码示例图如下

    在这里插入图片描述

  • 与properties配置文件结合给属性赋值的步骤

    • Step1: 在pom.xml文件中导入Spring、Annotation、数据源(连接池)的坐标和数据库mysql驱动坐标。pom.xml文件完整代码如下

      • 博主测试C3P0、Druid两个数据库连接池,所以它俩的坐标均会导入
      <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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>SpringDemo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>SpringAnno</artifactId><packaging>war</packaging><name>SpringAnno Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--mysql坐标--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--druid坐标--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.18</version></dependency><!--c3p0坐标--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!--spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version></dependency><!--Annotation坐标--><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies><build><finalName>SpringAnno</finalName><plugins><!-- Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build>
      </project>
      
    • Step2: 右键源代码配置文件目录(即资源文件resources)→NewFile,创建properties配置文件,博主文件名为jdbc.properties,该配置文件代码如下

      • 注意: properties配置文件中配置的各个属性前必须添加个id.(即id.属性,比如:属性url就设置为id.url,博主设置的为jdbc.url),以供Spring配置文件可以使用属性占位符${} 语法引用这些属性
      #driverClassName代表数据库驱动,后跟驱动全类名(在MySQL驱动jar包下的META-INF下的services文件夹下的java.sql.Driver文件内)
      jdbc.driverClassName=com.mysql.cj.jdbc.Driver
      # 数据库连接URL
      jdbc.url=jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
      # 数据库用户名
      jdbc.username=root
      # 数据库密码
      jdbc.password=123456
      # 初始化连接数量---即容器中初始的数据库连接数量
      jdbc.initialSize=5
      # 最大活跃连接数量---容器中初始为5个,但若5个用完了,此时可以在申请5个数据库连接数量
      #也就是说容器中最多存放10个数据库连接
      jdbc.maxActive=10
      # 获取连接时的最大等待时间,单位:毫秒。---与数据库进行连接时若超过3s仍未连接成功,则会报错
      jdbc.maxWait=3000
      #最小空闲连接数量---minIdle=5
      # 配置检测连接是否有效的SQL,可以是一个查询语句,如果不指定则默认为"SELECT 1"---validationQuery=SELECT 1
      # 是否开启自动提交事务---defaultAutoCommit=true
      
    • Step3: 右键源代码配置文件目录(即资源文件resources)→NewXML Configuration FileSpring Config,文件名为applicationContext.xml,然后在该Spring配置文件中引入context命名空间、context约束路径、配置注解的组件扫描,并引入properties配置文件后配置数据源(连接池)的bean。Spring配置文件完整代码如下

      <?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--配置注解的组件扫描--><context:component-scan base-package="at.guigu"></context:component-scan><!--使用`context`命名空间加载 `properties` 文件--><context:property-placeholder location="classpath:jdbc.properties"/><!--Cp30对应的bean--><bean id="dataSourceCp30" class="com.mchange.v2.c3p0.ComboPooledDataSource"><!--使用属性占位符`${}`语法引用properties文件中的属性--><property name="driverClass" value="${jdbc.driverClassName}"/><property name="jdbcUrl" value="${jdbc.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--Druid对应的bean--><bean id="dataSourceDruid" class="com.alibaba.druid.pool.DruidDataSource"><!--使用属性占位符`${}`语法引用properties文件中的属性--><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean>
      </beans>
      
    • Step4: BookServiceImpl类属性配置代码如下

      package at.guigu.service.impl;
      import at.guigu.dao.UserDao;
      import at.guigu.service.BookService;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.stereotype.Service;import javax.annotation.Resource;//<bean id="bookServiceImpl" class="at.guigu.service.impl.BookServiceImpl"></bean>
      @Service("bookServiceImpl")
      public class BookServiceImpl implements BookService {// <property name="userDao" ref="userDaoImpl"/>@Resource(name = "userDaoImpl")private UserDao userDao;@Value("${jdbc.driverClassName}")private String driverClass;@Value("${jdbc.username}")private String name;@Value("15")private int age;@Overridepublic void save() {System.out.println(driverClass);System.out.println(name + "===" + age);userDao.save();}
      }
      
    • Step5: 测试代码如下

      package at.guigu.web;import at.guigu.service.impl.BookServiceImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestOne {@Testpublic void test1() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      在这里插入图片描述

@PostConstruct@PreDestroy:初始、销毁方法

  • 繁琐配置步骤均省略,可详见之前的步骤,此处只说明重点步骤

    • BookServiceImpl类代码如下

      package at.guigu.service.impl;
      import at.guigu.dao.UserDao;
      import at.guigu.service.BookService;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.context.annotation.Scope;
      import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;
      import javax.annotation.PreDestroy;
      import javax.annotation.Resource;//<bean id="bookServiceImpl" scope = "singleton" class="at.guigu.service.impl.BookServiceImpl"></bean>
      @Service("bookServiceImpl")
      @Scope("singleton")
      public class BookServiceImpl implements BookService {// <property name="userDao" ref="userDaoImpl"/>@Resource(name = "userDaoImpl")private UserDao userDao;@PostConstructpublic void init() {System.out.println("Service Init...");}@PreDestroypublic void destroy() {System.out.println("Service Destroy...");}@Overridepublic void save() {System.out.println("BookService running...");userDao.save();}
      }
      
    • 测试代码如下

      package at.guigu.web;import at.guigu.service.impl.BookServiceImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestOne {@Testpublic void test2() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      在这里插入图片描述

  • 注意:在上述测试代码运行截图中并未运行销毁方法,原因及解决方式请详见本章中的Spring配置文件标签详解一中的初始销毁知识点

Spring新注解

  • 作用:配合Spring原始注解完全代替Spring配置文件

  • 可替代的配置如下

    • 非自定义的Bean的配置,比如Druid、Cp30的bean
    • 加载properties配置文件的配置:<context:property-placeholder location="classpath:jdbc.properties"/>
    • 组件扫描的配置(若有多个包则中间用逗号或空格间隔):<context:component-scan base-package="at.guigu"></context:component-scan>
      • <context:component-scan base-package="at.guigu.dao at.guigu.service"></context:component-scan>
      • <context:component-scan base-package="at.guigu.dao, at.guigu.service"></context:component-scan>
    • 引入其它配置文件的配置:<import resource="applicationContext-xxx.xml"/>
新注解解释
@Configuration使用在类上,用于指定当前类是Spring的核心配置类。当创建容器时会从该类上加载注解
@ComponentScan用于指定Spring在初始化容器时要扫描的包。即相当于组件扫描的配置。若扫描一个包,则为:@ComponentScan("包1");若扫描多个包,则为:@ComponentScan({"包1", "包2", ...})
@Bean使用在方法上,标注将该方法的返回值存储到容器中
@PropertySource用于加载properties文件的配置
@Import用于导入其它文件的配置类。若只导入一个文件配置类,则为@Import(Aaa.class);若导入多个,则为@Import({Aaa.class, Bbb.class})
@ComponentScan注解可能用到的属性解释
value/basePackages指定要扫描的包
includeFilters用于指定一个或多个包含过滤器,限制只有符合条件的类才会被扫描和注册为 Spring Bean。过滤条件可以是注解、正则表达式等。
excludeFilters用于指定一个或多个排除过滤器,排除掉不需要扫描的类。它和 includeFilters 是互斥的
@ComponentScan注解的内部注解解释
@ComponentScan.Filter用于定义在组件扫描时的过滤规则。主要用于 includeFiltersexcludeFilters 属性,用来实现扫描范围的精确控制。
@ComponentScan.Filter注解用到的属性解释
type指定过滤的类型。共有四种即FilterType.ANNOTATION:根据注解类型过滤类;FilterType.REGEX:使用正则表达式过滤类的全限定名;FilterType.ASPECTJ:使用 AspectJ 表达式进行过滤;FilterType.ANY:匹配所有类,不常用。
value/classes根据过滤类型不同,指定具体的过滤条件。如果 typeFilterType.ANNOTATION,则 value 是要过滤的注解类型;如果 typeFilterType.ASPECTJ,则 value 是 AspectJ 表达式。
pattern根据过滤类型不同,指定具体的过滤条件。如果 typeFilterType.REGEX,则用pattern 要匹配的正则表达式

注意: @ComponentScan注解中的属性及内部注解示例可详见SpringMVC注解形式的快速入门示例

Spring新注解代码实现

  • Spring新注解快速入门的UserDaoImpl类、BookServiceImpl类代码省略,详见Spring原始注解快速入门

  • 在Spring原始注解中,利用@Value()注解注入普通属性时有一个与properties配置文件结合给属性赋值的步骤

    • 该步骤的Step3中的Spring配置文件代码如下

      <?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--配置注解的组件扫描--><context:component-scan base-package="at.guigu"></context:component-scan><!--使用`context`命名空间加载 `properties` 文件--><context:property-placeholder location="classpath:jdbc.properties"/><!--Cp30对应的bean--><bean id="dataSourceCp30" class="com.mchange.v2.c3p0.ComboPooledDataSource"><!--使用属性占位符`${}`语法引用properties文件中的属性--><property name="driverClass" value="${jdbc.driverClassName}"/><property name="jdbcUrl" value="${jdbc.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--Druid对应的bean--><bean id="dataSourceDruid" class="com.alibaba.druid.pool.DruidDataSource"><!--使用属性占位符`${}`语法引用properties文件中的属性--><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean>
      </beans>
      
  • 利用新注解进行配置的步骤如下

    • Step1: 在pom.xml文件中导入Spring、Annotation、数据源(连接池)的坐标和数据库mysql驱动坐标。pom.xml文件完整代码如下

      • 博主测试C3P0、Druid两个数据库连接池,所以它俩的坐标均会导入
      <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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>SpringDemo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>SpringAnno</artifactId><packaging>war</packaging><name>SpringAnno Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--mysql坐标--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--druid坐标--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.18</version></dependency><!--c3p0坐标--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!--spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version></dependency><!--Annotation坐标--><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies><build><finalName>SpringAnno</finalName><plugins><!-- Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build>
      </project>
      
    • Step2: 右键源代码配置文件目录(即资源文件resources)→NewFile,创建properties配置文件,博主文件名为jdbc.properties,该配置文件代码如下

      • 注意: properties配置文件中配置的各个属性前必须添加个id.(即id.属性,比如:属性url就设置为id.url,博主设置的为jdbc.url),以供Spring配置文件可以使用属性占位符${} 语法引用这些属性
      #driverClassName代表数据库驱动,后跟驱动全类名(在MySQL驱动jar包下的META-INF下的services文件夹下的java.sql.Driver文件内)
      jdbc.driverClassName=com.mysql.cj.jdbc.Driver
      # 数据库连接URL
      jdbc.url=jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
      # 数据库用户名
      jdbc.username=root
      # 数据库密码
      jdbc.password=123456
      # 初始化连接数量---即容器中初始的数据库连接数量
      jdbc.initialSize=5
      # 最大活跃连接数量---容器中初始为5个,但若5个用完了,此时可以在申请5个数据库连接数量
      #也就是说容器中最多存放10个数据库连接
      jdbc.maxActive=10
      # 获取连接时的最大等待时间,单位:毫秒。---与数据库进行连接时若超过3s仍未连接成功,则会报错
      jdbc.maxWait=3000
      #最小空闲连接数量---minIdle=5
      # 配置检测连接是否有效的SQL,可以是一个查询语句,如果不指定则默认为"SELECT 1"---validationQuery=SELECT 1
      # 是否开启自动提交事务---defaultAutoCommit=true
      
    • Step4: 在三层架构包下创建一个config包,并在该包下创建一个**代替Spring配置文件的类** SpringConfiguration,完整代码如下

      package at.guigu.config;import com.alibaba.druid.pool.DruidDataSource;
      import com.mchange.v2.c3p0.ComboPooledDataSource;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.context.annotation.PropertySource;import javax.sql.DataSource;// 该注解代表该类是Spring的核心配置类
      @Configuration
      // 配置注解的组件扫描<context:component-scan base-package="at.guigu"></context:component-scan>
      @ComponentScan("at.guigu")
      // 加载properties配置文件<context:property-placeholder location="classpath:jdbc.properties"/>
      @PropertySource("classpath:jdbc.properties")
      public class SpringConfiguration {@Value("${jdbc.driverClassName}")private String driverClassName;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;/*** Cp30对应的bean* Spring会将当前方法的返回值以指定的id存储到Spring的IOC容器中* @return* @throws Exception*/@Bean("dataSourceCp30")public DataSource getCp30DataSource() throws Exception{// 创建数据源对象ComboPooledDataSource dataSource = new ComboPooledDataSource();// 设置数据源基本连接数据dataSource.setDriverClass(driverClassName);dataSource.setJdbcUrl(url);dataSource.setUser(username);dataSource.setPassword(password);return dataSource;}/*** Druid对应的bean* Spring会将当前方法的返回值以指定的id存储到Spring的IOC容器中* @return* @throws Exception*/@Bean("dataSourceDruid")public DataSource getDruidDataSource() throws Exception{// 创建数据源对象DruidDataSource dataSource = new DruidDataSource();// 设置数据源基本连接数据dataSource.setDriverClassName(driverClassName);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}
      }
      
    • 测试代码如下

      package at.guigu.web;import at.guigu.config.SpringConfiguration;
      import at.guigu.service.impl.BookServiceImpl;
      import com.mchange.v2.c3p0.ComboPooledDataSource;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestOne {@Testpublic void test3() {//1 获取IOC容器// 通过Spring配置文件获取:ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");// 通过Spring类获取ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}@Testpublic void test4() {//1 获取IOC容器// 通过Spring配置文件获取:ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");// 通过Spring类获取ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);//2 从IOC容器中获取bean对应的对象ComboPooledDataSource dataSourceCp30 = (ComboPooledDataSource) app.getBean("dataSourceCp30");System.out.println(dataSourceCp30);}
      }
      
  • 在实际开发中代替Spring配置文件的SpringConfiguration类中的代码会很多,我们可以将其根据不同种类拆分开,然后在主Spring配置文件对应的类中引入拆分后的类,代码如下

    • Step1:config包下创建拆分配置文件对应的拆分类DataSourceConfiguration,代码如下

      package at.guigu.config;import com.alibaba.druid.pool.DruidDataSource;
      import com.mchange.v2.c3p0.ComboPooledDataSource;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.PropertySource;import javax.sql.DataSource;// 分配置文件对应的类不用配置@Configuration以及@ComponentScan注解
      // 加载properties配置文件<context:property-placeholder location="classpath:jdbc.properties"/>
      @PropertySource("classpath:jdbc.properties")
      public class DataSourceConfiguration {@Value("${jdbc.driverClassName}")private String driverClassName;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;/*** Cp30对应的bean* Spring会将当前方法的返回值以指定的id存储到Spring的IOC容器中* @return* @throws Exception*/@Bean("dataSourceCp30")public DataSource getCp30DataSource() throws Exception{// 创建数据源对象ComboPooledDataSource dataSource = new ComboPooledDataSource();// 设置数据源基本连接数据dataSource.setDriverClass(driverClassName);dataSource.setJdbcUrl(url);dataSource.setUser(username);dataSource.setPassword(password);return dataSource;}/*** Druid对应的bean* Spring会将当前方法的返回值以指定的id存储到Spring的IOC容器中* @return* @throws Exception*/@Bean("dataSourceDruid")public DataSource getDruidDataSource() throws Exception{// 创建数据源对象DruidDataSource dataSource = new DruidDataSource();// 设置数据源基本连接数据dataSource.setDriverClassName(driverClassName);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}
      }
      
    • Step2: 在Spring主配置文件对应的主类SpringConfiguration中利用@Import注解引入分配置文件对应的拆分类DataSourceConfiguration,代码如下:

      package at.guigu.config;import com.alibaba.druid.pool.DruidDataSource;
      import com.mchange.v2.c3p0.ComboPooledDataSource;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.context.annotation.*;import javax.sql.DataSource;// 该注解代表该类是Spring的核心配置类
      @Configuration
      // 配置注解的组件扫描<context:component-scan base-package="at.guigu"></context:component-scan>
      @ComponentScan("at.guigu")
      // 引入拆分配置文件<import resource="applicationContext-xxx.xml"/>
      @Import(DataSourceConfiguration.class)
      public class SpringConfiguration {
      }
      

为非自定义(即第三方)的bean注入资源

  • 以数据源为例,假设现在容器中的数据源需要使用UserDao实现类的对象(即引用类型),此时直接将其作为形式参数传递给数据源方法中即可,因为Spring在检测到该数据源bean为第三方bean时,会自动为其提供IOC容器中参数所对应引用类型的bean,代码如下

    package at.guigu.config;import com.alibaba.druid.pool.DruidDataSource;
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.PropertySource;import javax.sql.DataSource;// 分配置文件对应的类不用配置@Configuration以及@ComponentScan注解
    // 加载properties配置文件<context:property-placeholder location="classpath:jdbc.properties"/>
    @PropertySource("classpath:jdbc.properties")
    public class DataSourceConfiguration {@Value("${jdbc.driverClassName}")private String driverClassName;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;/*** Cp30对应的bean* Spring会将当前方法的返回值以指定的id存储到Spring的IOC容器中* @return* @throws Exception*/@Bean("dataSourceCp30")public DataSource getCp30DataSource(BookService bookService) throws Exception{System.out.println(bookService);// 创建数据源对象ComboPooledDataSource dataSource = new ComboPooledDataSource();// 设置数据源基本连接数据dataSource.setDriverClass(driverClassName);dataSource.setJdbcUrl(url);dataSource.setUser(username);dataSource.setPassword(password);return dataSource;}/*** Druid对应的bean* Spring会将当前方法的返回值以指定的id存储到Spring的IOC容器中* @return* @throws Exception*/@Bean("dataSourceDruid")public DataSource getDruidDataSource(BookService bookService) throws Exception{System.out.println(bookService);// 创建数据源对象DruidDataSource dataSource = new DruidDataSource();// 设置数据源基本连接数据dataSource.setDriverClassName(driverClassName);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}
    }
    

    此处不在进行运行示例

Spring集成Junit

  • 原始Junit测试Spring的问题

    • 在测试类中均需要以下两行代码,这两行代码若不写的话就会造成空指针异常

      //1 获取IOC容器
      // 通过Spring配置文件获取:ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
      // 通过Spring类获取
      ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
      //2 从IOC容器中获取bean对应的对象
      ComboPooledDataSource dataSourceCp30 = (ComboPooledDataSource) app.getBean("dataSourceCp30");
      
  • 解决原始Junit测试Spring问题的方案

    • 让SpringJunit负责创建Spring容器,但需要将配置文件或配置类告知,然后将需要进行测试的bean直接在测试类中进行注入

Spring集成Junit代码实现

  • Spring集成Junit步骤

    • 导入相关坐标

      • 导入Spring基础坐标:spring-context
      • 导入Spring提供的监听器ContextLoaderListener的相关坐标:spring-web
      • 导入Spring集成Web环境相关坐标:servlet、jsp
      • 导入Spring注解相关坐标:Annotation
      • 导入数据库相关坐标:mysql、数据源坐标(druid、cp30)
      • 导入Spring集成JUnit相关坐标:junit、spring-test
      • 导入Spring集成MyBatis相关坐标:mybatis、spring-jdbc、mybatis-spring
    • 使用@Runwith注解替换原来的运行器,并设置新的类运行器

      • 其属性为SpringRunner.classSpringJUnit4ClassRunner.class:用于集成 Spring 测试框架
    • 使用@ContextConfiguration指定Spring配置文件或Spring配置类

      • 指定Spring配置文件:@ContextConfiguration("classpath:applicationContext.xml")
      • 指定单个Spring配置类:@ContextConfiguration(classes = SpringConfiguration.class)
      • 指定多个Spring配置类:@ContextConfiguration(classes = {SpringConfiguration.class,...})
    • 在该类中使用@Autowired注入需要测试的对象

    • 在该类中创建对应测试方法测试对应方法

  • 步骤如下

    • 该步骤有两种形式

      • Spring配置文件的形式:Spring配置文件及与之对应的UserDaoImplBookServiceImpl代码均省略
      • Spring配置类的形式:Spring配置类及与之对应的UserDaoImplBookServiceImpl代码均省略,可详见Spring注解开发部分内容
    • Step1: 导入Spring集成Junit的坐标,即spring-test坐标

      • 除了Junit坐标外还有spring、Annotation、数据源(连接池)的坐标和数据库mysql驱动坐标。pom.xml文件完整代码如下
      <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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>SpringDemo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>SpringAnno</artifactId><packaging>war</packaging><name>SpringAnno Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--mysql坐标--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--druid坐标--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.18</version></dependency><!--c3p0坐标--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!--spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version></dependency><!--Annotation坐标--><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!--spring-test坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>6.1.6</version><scope>test</scope></dependency></dependencies><build><finalName>SpringAnno</finalName><plugins><!-- Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build>
      </project>
      
    • Step2: 创建测试类TestTwo。代码如下

      • Spring配置文件的形式
      package at.guigu.web;import at.guigu.service.BookService;
      import at.guigu.service.impl.BookServiceImpl;
      import org.junit.Test;
      import org.junit.runner.RunWith;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.test.context.ContextConfiguration;
      import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;// 1 集成 Spring 测试框架
      @RunWith(SpringJUnit4ClassRunner.class)
      // 2 指定Spring配置文件或Spring配置类
      @ContextConfiguration("classpath:applicationContext.xml")
      public class TestTwo {// 3 注入需要测试的对象@Autowiredprivate BookServiceImpl bookService;// 3 注入需要测试的对象:若需要测试的bean有多个则与@Qualifier结合指定对应id的bean@Autowired@Qualifier("dataSourceDruid")private DataSource dataSourceDruid;// 3 注入需要测试的对象:若需要测试的bean有多个则与@Qualifier结合指定对应id的bean@Autowired@Qualifier("dataSourceCp30")private DataSource dataSourceCp30;// 4 创建测试方法进行测试@Testpublic void test1() {bookServiceImpl.save();System.out.println(dataSourceDruid);System.out.println(dataSourceCp30);}
      }
      
      • Spring配置类的形式
      package at.guigu.web;import at.guigu.config.SpringConfiguration;
      import at.guigu.service.BookService;
      import at.guigu.service.impl.BookServiceImpl;
      import com.mchange.v2.c3p0.ComboPooledDataSource;
      import org.junit.Test;
      import org.junit.runner.RunWith;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      import org.springframework.test.context.ContextConfiguration;
      import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import javax.sql.DataSource;// 1 集成 Spring 测试框架
      @RunWith(SpringJUnit4ClassRunner.class)
      // 2 指定Spring配置文件或Spring配置类
      @ContextConfiguration(classes = {SpringConfiguration.class})
      public class TestTwo {// 3 注入需要测试的对象@Autowiredprivate BookService bookServiceImpl;// 3 注入需要测试的对象:若需要测试的bean有多个则与@Qualifier结合指定对应id的bean@Autowired@Qualifier("dataSourceDruid")private DataSource dataSourceDruid;// 3 注入需要测试的对象:若需要测试的bean有多个则与@Qualifier结合指定对应id的bean@Autowired@Qualifier("dataSourceCp30")private DataSource dataSourceCp30;// 4 创建测试方法进行测试@Testpublic void test1() {bookServiceImpl.save();System.out.println(dataSourceDruid);System.out.println(dataSourceCp30);}
      }
      

      在这里插入图片描述

完整注解形式集成Junit代码实现

以Spring集成MyBatis项目为基础进行集成测试,要求:在maven项目的test包下完成测试(以测试业务层service包下的类为例)

  • Step1: 导入相关坐标,完整文件代码如下

    • 导入Spring基础坐标:spring-context
    • 导入Spring提供的监听器ContextLoaderListener的相关坐标:spring-web
    • 导入Spring集成Web环境相关坐标:servlet、jsp
    • 导入Spring注解相关坐标:Annotation
    • 导入数据库相关坐标:mysql、数据源坐标(druid、cp30)
    • 导入Spring集成JUnit相关坐标:junit、spring-test
    • 导入Spring集成MyBatis相关坐标:mybatis、spring-jdbc、mybatis-spring
    <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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>SpringJunitDemo</artifactId><packaging>war</packaging><version>1.0-SNAPSHOT</version><name>SpringJunitDemo Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--===================Spring基础坐标=======================--><!--spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version></dependency><!--===================Spring自带监听器ContextLoaderListener所需坐标=======================--><!--spring-web--><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.2.25.RELEASE</version></dependency><!--===================Spring集成Web环境相关坐标=======================--><!-- servlet--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency><!--jsp--><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.3</version><scope>provided</scope></dependency><!--===================Spring注解相关坐标=======================--><!--Annotation坐标--><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version></dependency><!--=====================数据库相关坐标=========================--><!--mysql坐标--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--druid坐标--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.18</version></dependency><!--c3p0坐标--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!--===================Spring集成junit相关坐标=======================--><!--junit坐标--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!--spring-test坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>6.1.6</version><scope>test</scope></dependency><!--=====================MyBatis相关坐标=========================--><!--MyBatis坐标--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.16</version></dependency><!--mybatis-spring--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>3.0.3</version></dependency><!--spring-jdbc--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>6.1.10</version></dependency></dependencies><build><finalName>SpringJunitDemo</finalName><plugins><!-- Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build>
    </project>
    
  • Step2: 在test包下创建三层架构包的业务层service包,并在该包中创建BrandServiceTest测试类,完整代码如下

    • Step2-1: 该类要使用@Runwith注解替换原来的运行器,并设置新的类运行器
      • 其属性为SpringRunner.classSpringJUnit4ClassRunner.class:用于集成 Spring 测试框架
    • Step2-2: 该类使用@ContextConfiguration指定Spring配置文件或Spring配置类
      • 指定Spring配置文件:@ContextConfiguration("classpath:applicationContext.xml")
      • 指定单个Spring配置类:@ContextConfiguration(classes = SpringConfiguration.class)
      • 指定多个Spring配置类:@ContextConfiguration(classes = {SpringConfiguration.class,...})
    • Step2-3: 在该类中使用@Autowired注入需要测试的对象
    • Step2-4: 在该类中创建对应测试方法测试对应方法
    package at.guigu.service;import at.guigu.config.SpringConfiguration;
    import at.guigu.pojo.Brand;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.List;@RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = {SpringConfiguration.class})
    public class BrandServiceTest {@Autowiredprivate BrandService brandService;@Testpublic void testGetAll( ) {List<Brand> brands = brandService.getAll();for (Brand brand : brands) {System.out.println(brand);}}}
    

    运行该测试类,截图如下

    在这里插入图片描述

Spring集成Web环境

  • 即集成web/Controller表现层步骤

    • Step1: 在pom.xml文件中导入servlet和jsp坐标

      • 导入servlet和jsp坐标后三层架构中的web/Controller表现层才会起效
      • Spring需要导入的所有坐标:spring、spring-test、Annotation、servlet、jsp坐标。pom.xml文件完整代码如下
      <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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>SpringDemo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>SpringWeb</artifactId><packaging>war</packaging><name>SpringWeb Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--mysql坐标--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--druid坐标--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.18</version></dependency><!--c3p0坐标--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!--spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version></dependency><!--Annotation坐标--><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!--spring-test坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>6.1.6</version><scope>test</scope></dependency><!-- servlet--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency><!--jsp--><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.3</version><scope>provided</scope></dependency></dependencies><build><finalName>SpringWeb</finalName><plugins><!-- Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build>
      </project>
      
    • Step2: 创建三层架构,并写入对应接口和实现类,截图如下

      在这里插入图片描述

    • Step3: 配置properties以及Spring配置文件,截图如下

      在这里插入图片描述

    • Step4:web/Controller表现层下创建类BookServlet,代码如下

      package at.guigu.web;import at.guigu.service.impl.BookServiceImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;import javax.servlet.*;
      import javax.servlet.http.*;
      import javax.servlet.annotation.*;
      import javax.sql.DataSource;
      import java.io.IOException;// 此时url不通过@WebServlet注解进行配置,而是在web.xml中进行配置
      // @WebServlet("/bookServlet")
      public class BookServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookServiceImpl = (BookServiceImpl) app.getBean("bookServiceImpl");DataSource dataSourceDruid = (DataSource) app.getBean("dataSourceDruid");bookServiceImpl.save();System.out.println(dataSourceDruid);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
      }
      
    • Step5: 在web项目核心目录(即WEB-INF)下的web.xml文件中进行web配置,代码如下

      • 利用<servlet>标签声明Servlet
      • 利用<servlet-mapping>标签将URL模式映射到特定的Servlet上
      • <servlet>标签一定要在<servlet-mapping>标签之前,否则会报错
      <!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!--声明一个Servlet--><servlet><!--指定要声明的Servlet的类名--><servlet-name>BookServlet</servlet-name><!--声明的Servlet的全限定名--><servlet-class>at.guigu.web.BookServlet</servlet-class></servlet><!--将URL模式映射到特定的Servlet上--><servlet-mapping><!--指定的Servlet的类名--><servlet-name>BookServlet</servlet-name><!--给指定的Servlet设置url,相当于@WebServlet("/bookServlet")--><url-pattern>/bookServlet</url-pattern></servlet-mapping></web-app>
    • Step6: 利用Tomcat运行该Web项目,运行截图如下

      在这里插入图片描述

ApplicationContext应用上下文获取方式

  • 定义:应用上下文对象是通过new ClassPathXmlApplicationContext("spring配置文件");方式获取的,但是每次从容器中获得bean时都要编写该句代码,这就会造成代码冗余,配置文件加载多次,应用上下文对象创建多次

    • 解释:在Spring集成web环境中,其中Web层代码是通过Spring容器获取Service层的,即BookServlet类中的如下两句代码

      //1 获取IOC容器 (ApplicationContext应用上下文获取方式)
      ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
      //2 从IOC容器中获取bean对应的对象
      BookServiceImpl bookServiceImpl = (BookServiceImpl) app.getBean("bookServiceImpl");
      DataSource dataSourceDruid = (DataSource) app.getBean("dataSourceDruid");
      
    • 由于web/Controller表现层在后期会有很多业务(即很多Servlet类),所以就会造成代码冗余,配置文件加载多次,应用上下文对象创建多次

  • 解决方式

    在Web项目中,可以使用ServletContextListener监听Web应用的启动,我们可在Web应用启动时就加载Spring配置文件,创建Spring的应用上下文对象ApplicationContext,然后将其存储到最大的域servletContext对象中,这样就可以在任意位置从域中获取应用上下文ApplicationContext对象了

    监听器Listener知识点内容可详见Filter&Listener&AJAX&Axios&JSON

自定义ContextListener

  • 步骤

    • Step1:web包下创建listener包,定义一个实现ServletContextListener 接口的实现类ContextLoaderListener,代码及步骤如下

      package at.guigu.web.listener;import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;import javax.servlet.*;
      import javax.servlet.http.*;
      import javax.servlet.annotation.*;@WebListener
      public class ContextLoaderListener implements ServletContextListener {public ContextLoaderListener() {}@Overridepublic void contextInitialized(ServletContextEvent sce) {// 1 获取IOC容器,创建应用上下文对象`ApplicationContext` (ApplicationContext应用上下文获取方式)ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");// 2 获取最大域ServletContext对象ServletContext servletContext = sce.getServletContext();// 2 将Spring的应用上下文对象`ApplicationContext`存储到最大的域`servletContext`中servletContext.setAttribute("app", app);}@Overridepublic void contextDestroyed(ServletContextEvent sce) {}}
      
    • Step2: 在web项目核心目录(即WEB-INF)下的web.xml文件中进行监听器Listener配置,代码如下

      • <listener>标签一定要在<servlet>标签之前,否则会报错
      <!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><listener><listener-class>at.guigu.web.listener.ContextLoaderListener</listener-class></listener><servlet><servlet-name>BookServlet</servlet-name><servlet-class>at.guigu.web.BookServlet</servlet-class></servlet><servlet-mapping><servlet-name>BookServlet</servlet-name><url-pattern>/bookServlet</url-pattern></servlet-mapping></web-app>
      
    • Step3: web/Controller表现层下创建类BookServlet的代码更改如下

      package at.guigu.web;import at.guigu.service.impl.BookServiceImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;import javax.servlet.*;
      import javax.servlet.http.*;
      import javax.sql.DataSource;
      import java.io.IOException;public class BookServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1 获取最大域ServletContext对象ServletContext servletContext = request.getServletContext();// 2 通过最大域ServletContext对象获取Spring的应用上下文对象,即IOC容器ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");// 3 获取IOC容器中的beanBookServiceImpl bookServiceImpl = (BookServiceImpl) app.getBean("bookServiceImpl");DataSource dataSourceDruid = (DataSource) app.getBean("dataSourceDruid");bookServiceImpl.save();System.out.println(dataSourceDruid);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
      }
      
    • 然后利用Tomcat运行该Web项目即可

  • 在上述过程中,其中监听器ContextLoaderListener类中创建应用上下文对象ApplicationContext的那句代码需要传入Spring配置文件,这会造成耦合问题,因为我们可能会修改Spring配置文件的名称,为降低耦合,我们可将其进一步优化,步骤如下

    • Step1:在web项目核心目录(即WEB-INF)下的web.xml文件中添加一个<context-param>标签用于定义全局初始化参数,此处用于定义Spring配置文件供监听器使用,web.xml文件代码如下

      • 后期若Spring配置文件名字更改,我们就只需要更改web.xml文件中<context-param>标签中的子标签<param-value>的参数即可
      <!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!--全局初始化参数--><context-param><!--定义参数的名称,必须是唯一的--><param-name>contextConfigLocation</param-name><!--定义参数的值--><param-value>classpath:applicationContext.xml</param-value></context-param><!--监听器--><listener><!--监听器类的全限定名--><listener-class>at.guigu.web.listener.ContextLoaderListener</listener-class></listener><!--声明一个Servlet--><servlet><!--声明的Servlet的类名--><servlet-name>BookServlet</servlet-name><!--声明的Servlet的全限定名--><servlet-class>at.guigu.web.BookServlet</servlet-class></servlet><!--将URL模式映射到特定的Servlet上--><servlet-mapping><!--指定的Servlet的类名--><servlet-name>BookServlet</servlet-name><!--给指定的Servlet设置url,相当于@WebServlet("/bookServlet")--><url-pattern>/bookServlet</url-pattern></servlet-mapping></web-app>
      
    • Step2: 实现ServletContextListener 监听器接口的实现类ContextLoaderListener代码更改如下

      package at.guigu.web.listener;import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;import javax.servlet.*;
      import javax.servlet.http.*;
      import javax.servlet.annotation.*;@WebListener
      public class ContextLoaderListener implements ServletContextListener {public ContextLoaderListener() {}@Overridepublic void contextInitialized(ServletContextEvent sce) {// 1 获取最大域`servletContext`对象ServletContext servletContext = sce.getServletContext();// 2 通过最大域`servletContext`对象获取web.xml文件中的全局参数String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");// 3 获取IOC容器,创建应用上下文对象`ApplicationContext` (ApplicationContext应用上下文获取方式)ApplicationContext app = new ClassPathXmlApplicationContext(contextConfigLocation);// 4 将应用上下文对象`ApplicationContext`存入最大域中servletContext.setAttribute("app", app);}@Overridepublic void contextDestroyed(ServletContextEvent sce) {// 释放资源}}
      
  • 在上述优化后仍具有耦合,因为应用上下文对象的对象名是由开发人员在监听器对应的类中决定的,在Web层使用最大域对象来获取应用上下文对象时必须知道监听器类中所设置的对象名,这就具有耦合,为了解耦合,我们可以设置一个工具类,专门来返回应用上下文对象ApplicationContext在最大域中的键名,步骤如下

    • Step1: 在util包下创建工具类ApplicationContextUtil,该类代码如下

      package at.guigu.util;import org.springframework.context.ApplicationContext;import javax.servlet.ServletContext;public class ApplicationContextUtil {public static ApplicationContext getApplicationContext(ServletContext servletContext) {return (ApplicationContext) servletContext.getAttribute("app");}
      }
      
    • Step2: web/Controller表现层下创建类BookServlet的代码更改如下

      package at.guigu.web;import at.guigu.service.impl.BookServiceImpl;
      import at.guigu.util.ApplicationContextUtil;
      import com.alibaba.druid.pool.DruidDataSource;
      import org.springframework.context.ApplicationContext;import javax.servlet.*;
      import javax.servlet.http.*;
      import java.io.IOException;public class BookServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1 获取最大域ServletContext对象ServletContext servletContext = request.getServletContext();// 2 获取应用上下文对象(即IOC容器)ApplicationContext app = ApplicationContextUtil.getApplicationContext(servletContext);//3 获取beanBookServiceImpl bookServiceImpl = app.getBean(BookServiceImpl.class);//等同于BookServiceImpl bookServiceImpl = (BookServiceImpl) app.getBean("bookServiceImpl");DruidDataSource dataSourceDruid = app.getBean(DruidDataSource.class);//等同于DataSource dataSourceDruid = (DataSource) app.getBean("dataSourceDruid");bookServiceImpl.save();System.out.println(dataSourceDruid);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
      }
      

优化后完整步骤方式一(使用自己创建的监听器类)

  • Step1: 在pom.xml文件中导入坐标:spring、Annotation、spring-test、servlet、jsp以及Tomcat插件

    • 若需要mysql及数据源(数据库连接池),则导入坐标:mysql、druid、c3p0

    • 所有坐标代码如下

      <!--mysql坐标-->
      <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version>
      </dependency><!--druid坐标-->
      <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.18</version>
      </dependency><!--c3p0坐标-->
      <dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version>
      </dependency><!--spring坐标-->
      <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version>
      </dependency><!--Annotation坐标-->
      <dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version>
      </dependency>
      <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope>
      </dependency><!--spring-test坐标-->
      <dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>6.1.6</version><scope>test</scope>
      </dependency><!-- servlet-->
      <dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope>
      </dependency><!--jsp-->
      <dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.3</version><scope>provided</scope>
      </dependency>
      
  • Step2: 创建三层架构,并写入对应接口和实现类,截图如下

    在这里插入图片描述

  • Step3: 配置properties以及Spring配置文件,截图如下

    在这里插入图片描述

  • **Step4:**在util包下创建工具类ApplicationContextUtil,该类代码如下

    package at.guigu.util;import org.springframework.context.ApplicationContext;import javax.servlet.ServletContext;public class ApplicationContextUtil {public static ApplicationContext getApplicationContext(ServletContext servletContext) {return (ApplicationContext) servletContext.getAttribute("app");}
    }
    
  • Step5: 在web包下创建listener包,并在listener包下创建实现ServletContextListener接口的监听器类ContextLoaderListener,代码如下

    package at.guigu.web.listener;import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;import javax.servlet.*;
    import javax.servlet.http.*;
    import javax.servlet.annotation.*;@WebListener
    public class ContextLoaderListener implements ServletContextListener {public ContextLoaderListener() {}@Overridepublic void contextInitialized(ServletContextEvent sce) {// 1 获取最大的域`servletContext`对象ServletContext servletContext = sce.getServletContext();// 2 利用`servletContext`对象读取web.xml文件中的全局参数String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");// 3 获取IOC容器:获取应用上下文对象`ApplicationContext` 并将其存储到最大域中servletContext.setAttribute("app", new ClassPathXmlApplicationContext(contextConfigLocation));/* 等同于ApplicationContext app = new ClassPathXmlApplicationContext(contextConfigLocation);servletContext.setAttribute("app", app);*/}@Overridepublic void contextDestroyed(ServletContextEvent sce) {// 释放资源}}
    
  • Step6:web/Controller表现层下创建类BookServlet,代码如下

    package at.guigu.web;import at.guigu.service.impl.BookServiceImpl;
    import at.guigu.util.ApplicationContextUtil;
    import com.alibaba.druid.pool.DruidDataSource;
    import org.springframework.context.ApplicationContext;import javax.servlet.*;
    import javax.servlet.http.*;
    import java.io.IOException;public class BookServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1 获取最大域ServletContext对象ServletContext servletContext = request.getServletContext();// 2 获取应用上下文对象(即IOC容器)ApplicationContext app = ApplicationContextUtil.getApplicationContext(servletContext);//3 获取beanBookServiceImpl bookServiceImpl = app.getBean(BookServiceImpl.class);//等同于BookServiceImpl bookServiceImpl = (BookServiceImpl) app.getBean("bookServiceImpl");DruidDataSource dataSourceDruid = app.getBean(DruidDataSource.class);//等同于DataSource dataSourceDruid = (DataSource) app.getBean("dataSourceDruid");bookServiceImpl.save();System.out.println(dataSourceDruid);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
    }
    
  • Step7: 在web项目核心目录(即WEB-INF)下的web.xml文件中进行:全局初始化参数监听器Listener配置web配置。完整代码如下

    <!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!--全局初始化参数--><context-param><!--定义参数的名称,必须是唯一的--><param-name>contextConfigLocation</param-name><!--定义参数的值--><param-value>classpath:applicationContext.xml</param-value></context-param><!--监听器--><listener><!--监听器类的全限定名--><listener-class>at.guigu.web.listener.ContextLoaderListener</listener-class></listener><!--声明一个Servlet--><servlet><!--声明的Servlet的类名--><servlet-name>BookServlet</servlet-name><!--声明的Servlet的全限定名--><servlet-class>at.guigu.web.BookServlet</servlet-class></servlet><!--将URL模式映射到特定的Servlet上--><servlet-mapping><!--指定的Servlet的类名--><servlet-name>BookServlet</servlet-name><!--给指定的Servlet设置url,相当于@WebServlet("/bookServlet")--><url-pattern>/bookServlet</url-pattern></servlet-mapping></web-app>
    
  • Step8: Tomcat运行该Web项目即可

优化后完整步骤方式二(使用Spring提供的监听器类)

  • 完整步骤方式二,已上传到Gitee,可自行下载

Spring配置文件的形式(非注解开发 )

  • 在优化后完整步骤方式一中使用的是我们自己创建的继承ServletContextListener接口的监听器类ContextLoaderListener

  • 此处我们使用Spring所提供的监听器ContextLoaderListener

    • 该监听器内部加载Spring配置文件,创建应用上下文对象,并存储到最大域ServletContext

    • 它提供了一个客户端工具类WebApplicationContextUtils供使用者获取应用上下文对象

    • 使用该监听器的步骤

      • 在web项目核心目录(即WEB-INF)下的web.xml文件中配置ContextLoaderListener 监听器(前提是要先导入**spring-web** 坐标)

        <!--必须为5.2.X.RELEASE版本,否则会报错使用WebApplicationContextUtils获取应用上下文对象会报错:需要的是Jakarta Servlet而不是Java Servlet-->
        <dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.2.25.RELEASE</version>
        </dependency>
        
      • 使用客户端工具类WebApplicationContextUtils获取应用上下文对象ApplicationContext

  • 实现步骤

    • Step1: 在pom.xml文件中导入坐标:spring、spring-web、spring-test、Annotation、servlet、jsp以及Tomcat插件

      • 若需要mysql及数据源(数据库连接池),则导入坐标:mysql、druid、c3p0
      • 若需要MyBatis,则导入:spring-jdbc、mybatis-spring、mybatis
      <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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>SpringDemo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>SpringWeb</artifactId><packaging>war</packaging><name>SpringWeb Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--===================Spring相关坐标=======================--><!--spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version></dependency><!--spring-web --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.2.25.RELEASE</version></dependency><!--spring-test坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>6.1.6</version><scope>test</scope></dependency><!--Annotation坐标--><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!-- servlet--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency><!--jsp--><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.3</version><scope>provided</scope></dependency><!--=====================数据库相关坐标=========================--><!--mysql坐标--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--druid坐标--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.18</version></dependency><!--c3p0坐标--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!--=====================MyBatis相关坐标=========================--><!--spring-jdbc--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>6.1.10</version></dependency><!--mybatis-spring--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>3.0.3</version></dependency><!--MyBatis坐标--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.16</version></dependency></dependencies><build><finalName>SpringWeb</finalName><plugins><!-- Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build>
      </project>
      
    • Step2: 创建三层架构,并写入对应接口和实现类,截图如下

      在这里插入图片描述

    • Step3: 配置properties以及Spring配置文件,截图如下

      在这里插入图片描述

    • Step4: 在web项目核心目录(即WEB-INF)下的web.xml文件中进行:全局初始化参数配置Spring所提供的ContextLoaderListener 监听器web配置。完整代码如下

      <!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!--全局初始化参数--><context-param><!--定义参数的名称,必须是唯一的--><param-name>contextConfigLocation</param-name><!--定义参数的值--><param-value>classpath:applicationContext.xml</param-value></context-param><!--监听器--><!--配置Spring所提供的`ContextLoaderListener` 监听器--><listener><!--监听器类的全限定名--><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!--声明一个Servlet--><servlet><!--声明的Servlet的类名--><servlet-name>BookServlet</servlet-name><!--声明的Servlet的全限定名--><servlet-class>at.guigu.web.BookServlet</servlet-class></servlet><!--将URL模式映射到特定的Servlet上--><servlet-mapping><!--指定的Servlet的类名--><servlet-name>BookServlet</servlet-name><!--给指定的Servlet设置url,相当于@WebServlet("/bookServlet")--><url-pattern>/bookServlet</url-pattern></servlet-mapping></web-app>
      
    • Step5:web/Controller表现层下创建类BookServlet,代码如下

      package at.guigu.web;import at.guigu.service.impl.BookServiceImpl;
      import com.alibaba.druid.pool.DruidDataSource;
      import org.springframework.context.ApplicationContext;
      import org.springframework.web.context.support.WebApplicationContextUtils;import javax.servlet.ServletContext;
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;public class BookServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {// 1 获取最大域ServletContext对象ServletContext servletContext = request.getSession().getServletContext();// 2 获取应用上下文对象(即IOC容器)ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);//3 获取beanBookServiceImpl bookServiceImpl = app.getBean(BookServiceImpl.class);//等同于BookServiceImpl bookServiceImpl = (BookServiceImpl) app.getBean("bookServiceImpl");DruidDataSource dataSourceDruid = app.getBean(DruidDataSource.class);//等同于DataSource dataSourceDruid = (DataSource) app.getBean("dataSourceDruid");bookServiceImpl.save();System.out.println(dataSourceDruid);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
      }
      

Spring配置类的形式(注解开发 )

  • Step1: 在pom.xml文件中导入坐标:spring、spring-web、spring-test、Annotation、servlet、jsp以及Tomcat插件

    • 若需要mysql及数据源(数据库连接池),则导入坐标:mysql、druid、c3p0
    • 若需要MyBatis,则导入:spring-jdbc、mybatis-spring、mybatis
    • pom.xml代码详见Spring配置文件的形式
  • Step2: 创建三层架构,并写入对应接口和实现类,并使用Spring注解开发截图如下

    在这里插入图片描述

  • Step3: 右键源代码配置文件目录(即资源文件resources)→NewFile,创建properties配置文件,博主文件名为jdbc.properties,该配置文件代码如下

    • 注意: properties配置文件中配置的各个属性前必须添加个id.(即id.属性,比如:属性url就设置为id.url,博主设置的为jdbc.url),以供Spring配置文件可以使用属性占位符${} 语法引用这些属性
    #driverClassName代表数据库驱动,后跟驱动全类名(在MySQL驱动jar包下的META-INF下的services文件夹下的java.sql.Driver文件内)
    jdbc.driverClassName=com.mysql.cj.jdbc.Driver
    # 数据库连接URL
    jdbc.url=jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    # 数据库用户名
    jdbc.username=root
    # 数据库密码
    jdbc.password=123456
    # 初始化连接数量---即容器中初始的数据库连接数量
    jdbc.initialSize=5
    # 最大活跃连接数量---容器中初始为5个,但若5个用完了,此时可以在申请5个数据库连接数量
    #也就是说容器中最多存放10个数据库连接
    jdbc.maxActive=10
    # 获取连接时的最大等待时间,单位:毫秒。---与数据库进行连接时若超过3s仍未连接成功,则会报错
    jdbc.maxWait=3000
    #最小空闲连接数量---minIdle=5
    # 配置检测连接是否有效的SQL,可以是一个查询语句,如果不指定则默认为"SELECT 1"---validationQuery=SELECT 1
    # 是否开启自动提交事务---defaultAutoCommit=true
    
  • Step4: 在三层架构包下创建一个config包,并在该包下创建一个**代替Spring配置文件的类** SpringConfiguration,完整代码如下

    package at.guigu.config;import com.alibaba.druid.pool.DruidDataSource;
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;import javax.sql.DataSource;// 该注解代表该类是Spring的核心配置类
    @Configuration
    // 配置注解的组件扫描<context:component-scan base-package="at.guigu"></context:component-scan>
    @ComponentScan("at.guigu")
    // 加载properties配置文件<context:property-placeholder location="classpath:jdbc.properties"/>
    @PropertySource("classpath:jdbc.properties")
    public class SpringConfiguration {@Value("${jdbc.driverClassName}")private String driverClassName;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;/*** Cp30对应的bean* Spring会将当前方法的返回值以指定的id存储到Spring的IOC容器中* @return* @throws Exception*/@Bean("dataSourceCp30")public DataSource getCp30DataSource() throws Exception{// 创建数据源对象ComboPooledDataSource dataSource = new ComboPooledDataSource();// 设置数据源基本连接数据dataSource.setDriverClass(driverClassName);dataSource.setJdbcUrl(url);dataSource.setUser(username);dataSource.setPassword(password);return dataSource;}/*** Druid对应的bean* Spring会将当前方法的返回值以指定的id存储到Spring的IOC容器中* @return* @throws Exception*/@Bean("dataSourceDruid")public DataSource getDruidDataSource() throws Exception{// 创建数据源对象DruidDataSource dataSource = new DruidDataSource();// 设置数据源基本连接数据dataSource.setDriverClassName(driverClassName);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}
    }
    
  • Step5: 在web项目核心目录(即WEB-INF)下的web.xml文件中进行:全局初始化参数配置Spring所提供的ContextLoaderListener 监听器web配置。完整代码如下

    <!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!--配置Spring配置类的全局初始化参数--><context-param><param-name>contextClass</param-name><param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value></context-param><context-param><!--定义参数的名称,必须是唯一的--><param-name>contextConfigLocation</param-name><!--定义参数的值--><param-value>at.guigu.config.SpringConfiguration</param-value></context-param><!--监听器--><!--配置Spring所提供的`ContextLoaderListener` 监听器--><listener><!--监听器类的全限定名--><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!--声明一个Servlet--><servlet><!--声明的Servlet的类名--><servlet-name>UserServlet</servlet-name><!--声明的Servlet的全限定名--><servlet-class>at.guigu.web.UserServlet</servlet-class></servlet><!--将URL模式映射到特定的Servlet上(即UserServlet)--><servlet-mapping><!--指定的Servlet的类名--><servlet-name>UserServlet</servlet-name><!--给指定的Servlet设置url,相当于@WebServlet("/userServlet")--><url-pattern>/userServlet</url-pattern></servlet-mapping></web-app>
    
  • Step6: 在web层下创建UserServlet类,代码如下

    package at.guigu.web;import at.guigu.service.impl.UserServiceImpl;
    import com.alibaba.druid.pool.DruidDataSource;
    import org.springframework.context.ApplicationContext;
    import org.springframework.web.context.support.WebApplicationContextUtils;import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;public class UserServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1 获取最大域ServletContext对象ServletContext servletContext = request.getServletContext();//等同于ServletContext servletContext = request.getSession().getServletContext();// 2 获取应用上下文对象(即IOC容器)ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);//3 获取beanUserServiceImpl userServiceImpl = app.getBean(UserServiceImpl.class);//等同于BookServiceImpl bookServiceImpl = (BookServiceImpl) app.getBean("bookServiceImpl");DruidDataSource dataSourceDruid = app.getBean(DruidDataSource.class);//等同于DataSource dataSourceDruid = (DataSource) app.getBean("dataSourceDruid");userServiceImpl.save();System.out.println(dataSourceDruid);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
    }
    

    Tomcat运行该Web项目后截图如下所示

    在这里插入图片描述

相关文章:

Spring完整知识点二

Spring注解开发 Spring是轻代码而重配置的框架&#xff0c;配置比较繁重&#xff0c;影响开发效率&#xff0c;所以注解开发是一种趋势&#xff0c;它能够代替xml配置文件&#xff0c;可以简化配置&#xff0c;提高开发效率Spring注解根据出现时间分类 Spring原始注解&#xf…...

GESP三级集训——课堂笔记(部分)

进制转换&#xff08;二进制、十进制、八进制、十六进制等&#xff09; 十进制&#xff08;逢十进一&#xff09;——Decimal 十进制是我们生活中最常见的进制&#xff0c;如“1”“23”“891”等&#xff1a; 进位过程如下&#xff1a;{1,2,3,4,5,6,7,8,9}{10,11,12,13,14,…...

Spring Boot接口返回统一格式

统一的标准数据格式好处 SpringBoot返回统一的标准数据格式主要有以下几点好处&#xff1a; 增强接口的可读性和可维护性&#xff0c;使得前端开发人员能够更加清晰地理解接口返回的数据结构&#xff0c;从而提高开发效率。 降低前后端耦合度&#xff0c;当后端需要修改返回数…...

Flink如何基于数据版本使用最新离线数据

业务场景 假设批量有一张商户表&#xff0c;表字段中有商户名称和商户分类两个字段。 批量需要将最新的商户名称和分类的映射关系推到hbase供实时使用。 原实现方案 a.原方案内容 为解决批量晚批问题&#xff0c;批量推送hbase表时一份数据产生两类rowkey&#xff1a;T-1和…...

软件开发中的常用性能指标

大家好&#xff01;我是今越。在软件开发中我们经常会遇到一些性能指标&#xff0c;下面就带大家一起来看看。 QPS Queries Per Second&#xff0c;每秒查询率&#xff0c;一台服务器每秒能够响应的查询次数。它是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准…...

cmakelist使用总结

支持能编译成在不同系统上运行程序的方法 我们代码就一份&#xff0c;但有时需要编译成arm32&#xff0c;有时需要编译成x86_64,或更多 1、首先先将代码定义一个名称&#xff1a; #将所有的源文件列为一个集合&#xff0c;集合名字叫做SRC_LISTS set(SRC_LISTS main.cpp A.cpp…...

准备阶段 Unity优化总纲

Unity优化总纲 我们在学习优化课程之前要预先做好准备功能 例如最主要是的接收到一个优化的任务&#xff0c;应该怎么做&#xff0c;其次怎么做&#xff0c;最后怎么做。 也要学习一些专业工具以及专业术语 了解游戏运行机制&#xff0c;在排查期间思路会更清晰 1.优化目的…...

ubuntu防火墙(三)——firewalld使用与讲解

本文是Linux下&#xff0c;用ufw实现端口关闭、流量控制(二) firewalld使用方式 firewalld 是一个动态管理防火墙的工具&#xff0c;主要用于 Linux 系统&#xff08;包括 Ubuntu 和 CentOS 等&#xff09;。它提供了一个基于区域&#xff08;zones&#xff09;和服务&#x…...

zookeeper 搭建集群

基础的java 环境先安好&#xff0c;选择3台虚拟机 ip 不一样 机器应为奇数个 zookeeper 奇数个节点实际上是(2*n-1) 比偶数台机器少一台解决成本,并且能够满足 zookeeper 集群过半选举leader 的规则 # 3台虚拟机 将zookeeper 解压到服务器上 #在 conf/ 目录下 找到zoo_s…...

Java——异常机制(下)

1 异常处理之(捕获异常) (一般处理运行时异常) (try-catch-finally子句) (finally一般用于文件最后关闭) (catch捕获的子类在前父类在后——>不然父类在前面都让父类捕获掉了&#xff0c;会报错) (Exception是父类放在最后&#xff0c;如果前面没有捕获到&#xff0c;就…...

centos 手动安装libcurl4-openssl-dev库

下载源代码 curl downloadshttps://curl.se/download/ 选择需要下载的版本&#xff0c;我下载的是8.11.0 解压 tar -zxvf curl-8.11.0 查看安装命令 查找INSTALL.md&#xff0c;一般在docs文件夹下 –prefix &#xff1a;指定安装路径&#xff08;默认安装在/usr/local&…...

JS学习(1)(基本概念与作用、与HTML、CSS区别)

目录 一、JavaScript是什么&#xff1f; &#xff08;1&#xff09;基本介绍 &#xff08;2&#xff09;简称&#xff1a;JS&#xff1f; 二、JavaScript的作用。 三、HTML、CSS、JS之间的关系。 &#xff08;1&#xff09;html、css。 &#xff08;2&#xff09;JavaScript。 …...

代码随想录算法训练营day50|动态规划12

不同的子序列 给定一个字符串 s 和一个字符串 t &#xff0c;计算在 s 的子序列中 t 出现的个数。、 编辑距离中的删除元素&#xff0c;其实就是直接变数字&#xff0c;其只删除原来的较长的数组里的元素 递推模拟&#xff0c;使用s的最后一个元素匹配&#xff0c;或者删除…...

JavaWeb学习(2)(Cookie原理(超详细)、HTTP无状态)

目录 一、HTTP无状态。 &#xff08;1&#xff09;"记住我"&#xff1f; &#xff08;2&#xff09;HTTP无状态。 &#xff08;3&#xff09;信息存储客户端中。如何处理&#xff1f; 1、loaclStorage与sessionStorage。 2、Cookie。 二、Cookie。 &#xff08;1&…...

java抽象类

目录 一.抽象类 1.什么是抽象类 2.抽象类特点 (1)抽象类不能直接实例化对象 (2)可以包含抽象方法和具体方法 (3)可以有构造方法 (4)抽象类必须被继承&#xff0c;并且继承后子类要重写父类中的抽象方法&#xff0c;否则子类也是抽象类&#xff0c;必须要使用 abstract 修…...

minio集群部署–linux环境

原文地址&#xff1a;minio集群部署–linux环境 – 无敌牛 欢迎参观我的个人博客&#xff1a;无敌牛 – 技术/著作/典籍/分享等 第一步&#xff1a;安装 有rpm、deb、和二进制文件安装方式。参考文档在&#xff1a;MinIO Object Storage for Linux — MinIO Object Storage …...

在vue3里使用scss实现简单的换肤功能

实现的换肤功能&#xff1a;主题色切换、亮色模式和暗黑模式切换、背景图切换 主题色就是网站主色&#xff0c;可以配置到组件库上面&#xff1b;亮色模式又分为两种风格&#xff1a;纯白风格和背景图风格&#xff0c;不需要背景图的话可以删掉这部分逻辑和相关定义&#xff1b…...

JavaScript编写css自定义属性

一、自定义属性 是在 CSS 中定义的变量&#xff0c;以 --开头。它们可以存储颜色、尺寸、字体等任何 CSS 值&#xff0c;并且可以在整个文档中重复使用。 :root {--primary-color: #3498db;--font-size: 16px; }body {color: var(--primary-color);font-size: var(--font-siz…...

我们来学webservie - WSDL

WSDL 题记WSDL系列文章 题记 举个例子 酒桌上大领导们谈笑风生&#xff0c;把酒临风,其喜洋洋者矣老张说能签下xx项目&#xff0c;一来证明了集团在行业中的翘楚地位&#xff0c;二来感谢各位领导给予的大力支持接下来的一周&#xff0c;项目经理、业务顾问相继入场&#xff0…...

【Agent】构建智能诗歌创作系统:基于多 Agent 的协同创作实现

在探索大语言模型的创意应用过程中&#xff0c;我们开发了一个基于多 Agent 的智能诗歌创作系统。本文将介绍如何通过多个专业化的 Agent 协同工作&#xff0c;实现根据地点和天气信息自动创作诗歌的功能。 GitHub Code 项目地址 核心架构设计 1. Agent 基类设计 from pydan…...

001 LVGL PC端模拟搭建

01 LVGL模拟器介绍 使用PC端软件模拟LVGL运行&#xff0c;而不需要任何嵌入式硬件 环境搭建&#xff1a;codeblocks-20.03mingw-setup 正常安装流程即可 工程获取&#xff1a;LVGL官网-> github仓库 本地安装包下载资源包 工程模版和软件安装包 补充&#xff1a;…...

AJAX三、XHR,基本使用,查询参数,数据提交,promise的三种状态,封装-简易axios-获取省份列表 / 获取地区列表 / 注册用户,天气预报

一、XMLHttpRequest基本使用 XMLHttpRequest&#xff08;XHR&#xff09;对象用于与服务器交互。 二、XMLHttpRequest-查询参数 语法: 用 & 符号分隔的键/值对列表 三、XMLHttpRequest-数据提交 核心步骤 : 1. 请求头 设置 Content-Type 2. 请求体 携带 符合要求 的数…...

mybatis之数据统计与自定义异常处理

文章目录 需求描述定义实体方式一、mybatisPlus实现方式二、自定义SQL实现简单查询过滤查询 异常处理1、SQL拼写异常 在使用Mybatis或MybatisPlus进行数据统计&#xff0c;在【 SpringBoot的Mybatis-plus实战之基础知识】中对mybatisplus引入有介绍&#xff0c;本次要使用其进…...

qt creator使用taglib读取音频元信息,windows平台vcpkg安装

注意&#xff1a;qt creator用的构建组件是qt 6.2.3 MSVC2019 64bit 安装vcpkg // 我的安装位置C:\vcpkg git clone https://github.com/microsoft/vcpkg.git C:\vcpkg cd C:\vcpkg .\bootstrap-vcpkg.bat// 设置系统环境变量 VCPKG_ROOT C:/vcpkg用vcpkg安装taglib vcpkg …...

设计模式之生成器模式

目录 1.简介 2.结构 3.使用场景 4.实例 5.优缺点 6.与其他模式的关系 7.总结 1.简介 生成器模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;它允许你通过一步一步构建复杂对象&#xff0c;而不是通过一个包含大量参数的构造函数或方法。该…...

python学opencv|读取图像(三)放大和缩小图像

【1】引言 前序已经学习了常规的图像读取操作和图像保存技巧&#xff0c;相关文章链接为&#xff1a; python学opencv|读取图像-CSDN博客 python学opencv|读取图像&#xff08;二&#xff09;保存彩色图像-CSDN博客 今天我们更近一步&#xff0c;学习放大和缩小图像的技巧&…...

1 数据库(上):MySQL的概述和安装、SQL简介、IDEA连接数据库使用图形化界面

文章目录 前言一、数据库相关的概念二、MySQL概述1 MySQL的安装和配置2 MySQL登录、退出&#xff08;1&#xff09;mysql -uroot -p1234 或者mysql -uroot -p ---- 登录&#xff08;2&#xff09;exit或者quit ---- 退出 3 远程登录服务器上的MySQL命令mysql -hip地址 -P3306 -…...

C++初阶—类与对象(中篇)

第一章&#xff1a;类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默认成员函数&#xff1a;用户没有显式实现&a…...

Leetcode15. 三数之和(HOT100)

链接 一般这种三数之和&#xff0c;四数之和都使用双指针&#xff0c;复杂度最优&#xff0c;次一级可使用哈希表。前者要求有序&#xff0c;后者空间上有花费。 题目&#xff1a; 题目要求答案中不能出现重复vector&#xff0c;比如{-1 1 0}和{-1 0 1}&#xff1b; 这两个…...

Oracle数据库小白备忘

sqlplus相关 导入sql文件 在sqlplus中&#xff0c;导入一个sql文件&#xff0c;是使用或者start。 如当前目录下有一个hello.sql&#xff0c;则可以使用 hello.sql 或者 start hello.sql 来进行导入&#xff0c;功能类似于mysql里面的source。 退出编辑模式 当使用sqlplus…...