Spring(一):概述,IOC(Bean管理),整合Web项目,整合JUnit单元测试

1 Spring框架的学习路线

Spring(一):IOC容器(Bean管理),Spring与Web项目整合

Spring(二):AOP(面向切面编程),Spring的JDBC模板类

Spring(三):Spring的事务管理,SSH整合开发,Hibernate逆向工程

2 Spring的框架概述

2.1 什么是Spring

Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。

EE开发分成三层结构: 

  WEB层:Spring MVC

  业务层:Bean管理:(Spring IOC) 

  持久层:Spring的JDBC模板,ORM模板用于整合其他的持久层框架

相关书籍: 

  Expert One-to-One J2EE Design and Development:J2EE的设计和开发(2002.EJB) 

  Expert One-to-One J2EE Development without EJB:J2EE不使用EJB的开发(@interface21)

2.2 为什么学习Spring

  • 方便解耦,简化开发:Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理
  • AOP编程的支持:Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
  • 声明式事务的支持:只需要通过配置就可以完成对事务的管理,而无需手动编程
  • 方便程序的测试:Spring对Junit4支持,可以通过注解方便的测试Spring程序
  • 方便集成各种优秀框架:Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
  • 降低JavaEE API的使用难度:Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

2.3 Spring的版本

Spring 3.X 和 Spring4.X

3 SpringIOC入门案例

3.1 快速搭建Spring项目

步骤一:下载Spring的开发jar包

http://repo.spring.io/webapp/search/artifact/?0&q=spring-framework 

解压(Spring目录结构) 

  docs:API和开发规范 

  libs:jar包和源码

  schema:约束

步骤二:创建web项目,引入Spring IOC开发包

IOC:Inverse of Control,控制反转,将对象的创建权反转给Spring

Spring IOC的核心内容:

引入jar包(符合上述IOC开发相关的jar包就行了,再加上日志记录相关两个jar包):

注:hibernate中的Slf4j包不做具体的日志记录,只是用于整合其他日志jar包。

步骤三:创建包结构,编写接口和实现类

步骤四:创建Spring的配置文件

首先在src目录下创建Spring的配置文件:applicationContext.xml。 

然后引入spring的bean约束(spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\xsd-config.html的最下面copy)。 

最后完成bean配置。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- Spring的快速入门=================== -->
    <bean id="userService" class="com.itheima.spring.demo1.UserServiceImpl">
        <!--属性依赖注入-->
        <property name="name" value="老王(XML)"/>
    </bean>
</beans>

步骤五:编写测试程序

新建SpringDemo1类:

@Test
/**
 * 传统方式开发:
 */
public void demo1(){
    UserServiceImpl userService = new UserServiceImpl();
    // 手动设置:
    userService.setName("老王");
    userService.sayHello();
}

@Test
/**
 * Spring框架开发:
 */
public void demo2(){
    // 使用Spring的工厂:
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    // 通过工厂获得类:
    UserService userService = (UserService) applicationContext.getBean("userService");
    userService.sayHello();
}

3.2 控制反转(IOC)和依赖注入(DI)

IOC:控制反转,将对象的创建权反转给Spring。

DI:依赖注入,必须将对象的创建权交给Spring,将对象所依赖的属性注入进来.

3.2.1 面向对象开发中类的三种关系

依赖(A依赖B):

public class A{
    private B b;
    public void setB(B b){
        this.b = b;
    }
}

继承:is a

聚合:has a。又分松散聚合关系与紧密聚合关系。

3.3 Spring的工厂

3.3.1 ApplicationContext

ApplicatioContext接口有两个实现类:

ClassPathXmlApplicationContext:加载类路径下Spring的配置文件

FileSystemXmlApplicationContext:加载本地磁盘下Spring的配置文件

/**
 * Spring框架开发:读取本地磁盘配置文件
 */
public void demo3(){
    // 使用Spring的工厂:
    ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:\\applicationContext.xml");
    // 通过工厂获得类:
    UserService userService = (UserService) applicationContext.getBean("userService");
    userService.sayHello();
}

关闭工厂的方法只有其子类中才有:

3.3.2 BeanFactory

3.3.3 ApplicationContext和BeanFactory的区别

ApplicationContext:在加载applicationContext.xml时就会创建类的实例

BeanFactory:是在调用getBean方法时才会生成类的实例

4 Spring的Bean管理

4.1 XML方式

4.1.1 Spring创建Bean的方式

4.1.1.1 使用无参数构造方法实例化Bean(默认)
<!-- 无参数的构造方法: -->
<bean id="bean1" class="com.itheima.spring.demo2.Bean1"></bean>
4.1.1.2 静态工厂实例化Bean

提供静态工厂:

public class Bean2Factory {
    public static Bean2 getBean2Instance(){
        return new Bean2();
    }
}

完成配置:

<!-- 静态工厂实例化 -->
<bean id="bean2" class="com.itheima.spring.demo2.Bean2Factory" factory-method="getBean2Instance"/>
4.1.1.3 实例工厂实例化Bean

提供实例工厂:

public class Bean3Factory {
    public Bean3 getBean3Instance(){
        return new Bean3();
    }
}

完成配置:

<!-- 实例工厂实例化 -->
<bean id="bean3Factory" class="com.itheima.spring.demo2.Bean3Factory"></bean>
<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3Instance"></bean>

4.1.2 bean的配置

4.1.2.1 属性id和name的区别

id:给Bean起名。在schema约束中要求采用的ID必须唯一,必须以字母开始,可以使用字母、数字、连字符、下划线、句号、冒号,不能出现特殊字符。如:<bean id=”bookAction”>

name:给Bean起名。没有采用ID的唯一约束,可以出现特殊字符。如果<bean>没有id属性的话,name属性可以当做id使用。

  注:整合struts1的时候需要包含特殊字符'/',如:<bean name=”/loginAction” >

其他属性还包括:class(Bean的全路径)、factory-bean、factory-method。

4.1.2.2 scope属性

指定Bean的作用范围,值包括:

  • singleton:单例(默认)
  • prototype:多例。action交给struts2管理时,默认是多例,交给spring管理时,需要设置scope="prototype"
  • request:应用在Web项目中,spring创建完对象后,将对象存入到request域中
  • session:应用在Web项目中,spring创建完对象后,将对象存入到session域中
  • globalsession:应用在Web项目中,应用在Porlet环境(主网站登陆之后子网站就不用再次登陆了,也就是单点登录)
4.1.2.3 init-method和destroy-method属性

Bean的生命周期相关属性。

init-method:初始化的时候执行的方法

destroy-method:销毁的时候执行的方法。使用该方法的前提:Bean生成必须是单例的,在工厂关闭的时候销毁。

<bean id="orderDao" class="com.itheima.spring.demo3.OrderDao"  init-method="setup" destroy-method="teardown"></bean>
4.1.2.4 Bean的生命周期

Bean的完整的生命周期有十一个步骤:

  1. instantiate bean对象实例化(执行bean的构造函数)
  2. populate properties封装属性
  3. 如果Bean实现BeanNameAware接口,执行setBeanName方法
  4. 如果Bean实现BeanFactoryAware接口或者ApplicationContextAware接口,执行设置工厂setBeanFactory方法或者上下文对象的setApplicationContext方法
  5. 如果存在类实现BeanPostProcessor接口(后处理Bean),执行postProcessBeforeInitialization方法
  6. 如果Bean实现InitializingBean接口,执行afterPropertiesSet方法
  7. 调用<bean init-method="init">指定的初始化方法
  8. 如果存在类实现BeanPostProcessor接口(后处理Bean),执行postProcessAfterInitialization方法
  9. 执行业务处理
  10. 如果Bean实现DisposableBean接口,执行destroy方法
  11. 调用<bean destroy-method="customerDestroy">指定的销毁方法

第3步和第4步让JavaBean了解Spring的容器,可以在bean中调用spring容器的方法。

第5步和第8步非常重要,BeanPostPorcessor作用是在Bean的实例化的过程中对Bean的功能进行增强。

  Factory hook(工厂钩子) that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.

增强一个Bean中某个方法的几种方式:

继承

  能够控制这类的构造!!!也就是自己能够创建该类的实例。

装饰者模式:

  被增强类和增强类实现相同的接口。

  在增强的类中获得到被增强类的引用。

  缺点:如果接口中方法太多,其他方法都需要原封不动地调用。

动态代理:

  比较灵活

  JDK动态代理前提:类实现接口

  对实现接口的类产生代理

4.1.3 属性注入

4.1.3.1 构造方法注入

实体类提供构造方法:

<bean id="car" class="com.itheima.spring.demo5.Car">
    <!-- 按属性名称-->
    <!-- <constructor-arg name="name" value="宝马"/>
    <constructor-arg name="price" value="500000"/> -->
    <!-- 按属性角标,type属性可以不加 -->
    <constructor-arg index="0" type="java.lang.String" value="奔驰"/>
    <constructor-arg index="1" value="800000"/>
</bean>
4.1.3.2 set方法注入

实体类需要提供属性的set方法

<bean id="car2" class="com.itheima.spring.demo5.Car2">
    <property name="name" value="奇瑞QQ"/>
    <property name="price" value="35000"/>
</bean>

<bean id="employee" class="com.itheima.spring.demo5.Employee">
    <property name="name" value="老王"/>
    <!-- ref属性指定值为一个bean -->
    <property name="car2" ref="car2"/>
</bean>
4.1.3.3 p名称空间的注入(Spring2.5提供)

set方法注入问题:属性一旦很多,就需要很多的property标签。

引入p名称空间约束:

<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:p="http://www.springframework.org/schema/p"
       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">

p名称空间注入语法:p:属性名=””或者p:属性名-ref=””

<bean id="car2" class="com.itheima.spring.demo5.Car2" p:name="长安奔奔" p:price="40000"/>
<bean id="employee" class="com.itheima.spring.demo5.Employee" p:name="隔壁老王" p:car2-ref="car2"></bean>
4.1.3.4 SpEL(Spring Expression Language)注入(Spring3.0提供)

语法:#{SpEL}

<bean id="car2" class="com.itheima.spring.demo5.Car2" >
    <property name="name" value="#{'法拉利'}"/>
    <property name="price" value="#{1200000}"/>
</bean>

<bean id="employee" class="com.itheima.spring.demo5.Employee">
    <property name="name" value="#{'豆豆'}"/>
    <!-- #{beanid}指定类类型属性的值 -->
    <property name="car2" value="#{car2}"/>
</bean>
<bean id="carInfo" class="com.itheima.spring.demo5.CarInfo"></bean>

<bean id="car2" class="com.itheima.spring.demo5.Car2" >
    <property name="name" value="#{carInfo.carName}"/>
    <property name="price" value="#{carInfo.calculatorPrice()}"/>
</bean>
4.1.3.5 数组,集合(List,Set,Map),Properties属性注入
<bean id="collectionBean" class="com.itheima.spring.demo6.CollectionBean">
    <!-- 数组属性注入 -->
    <property name="arrs" >
        <list>
            <value>老王</value>
            <value>凤姐</value>
            <value>如花</value>
        </list>
    </property>
    <!-- List属性注入 -->
    <property name="list">
        <list>
            <value>豆豆</value>
            <value>奶茶</value>
            <value>绿茶</value>
        </list>
    </property>
    <!-- Set属性注入 -->
    <property name="set">
        <set>
            <value>王尧</value>
            <value>刘健</value>
            <value>周玉</value>
        </set>
    </property>
    <!-- Map属性注入 -->
    <property name="map">
        <map>
            <entry key="老王2" value="38"/>
            <entry key="凤姐" value="38"/>
            <entry key="如花" value="29"/>
        </map>
    </property>
    <!-- Properties属性注入 -->
    <property name="properties">
        <props>
            <prop key="username">root</prop>
            <prop key="password">123</prop>
        </props>
    </property>
</bean>

4.2 注解方式

4.2.1 注解IOC的快速入门

步骤一:下载Spring的开发包

同3.1节的步骤一。

步骤二:创建web项目,引入Spring IOC开发包

同3.1节的步骤二。

步骤三:创建包结构,编写接口和实现类

同3.1节的步骤三。

步骤四:创建Spring配置文件,开启组件扫描

首先在src下创建applicationContext.xml文件。

然后除了引入spring的bean约束以外,还要引入context约束

最后开启Spring的组件扫描配置。

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

    <!-- 开启Spring组件扫描 -->
    <context:component-scan base-package="com.itheima.spring.demo1"/>
<beans>

开启组件扫描后,Spring会扫描base-package属性指定包里的所有类上的@Component注解。在这些类的属性上就可以使用属性注入的注解,比如@Value

多个包的扫描可以用逗号隔开,也可以直接扫描上层包,比如com.itheima.spring。

注:

context:component-scan:会扫描包,支持类上注解和Resource注解

context:annotation-config:只支持不是类上的注解

步骤五:在类上添加注解

@Component(value="userService")

不配value默认将类名首字母小写后作为id

相当于xml方式的:<bean id=”userService” class=”...”/>

步骤六:在属性上添加注解

普通属性:@Value(value="老王")

属性就不需要提供set方法了

步骤七:编写测试类
@Test
public void demo2() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
            "applicationContext.xml");
    UserService userServie = (UserService)applicationContext.getBean("userService");
    userServie.sayHello();
}

4.2.2 Spring的Bean管理的常用注解

4.2.2.1 组件注解@Component

作用在类上。

Spring提供了@Component的三个衍生注解,功能目前来讲是一致的:

@Controller:作用在Controller层的类上
@Service:作用在Service层的类上
@Repository:作用在DAO层的类上

这三个注解是为了让标注类本身的用途清晰,Spring在后续版本会对其增强

4.2.2.2 属性注入注解

在类中的属性上使用属性注入注解时,对应属性可以不提供setter方法。

属性注入注解有:

@Value:用于注入普通类型属性,比如String类型。其value属性指定要注入的属性值。

@Autowired:自动装配,用于注入类类型属性,默认按类的类型进行注入(装配)。默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,例如:@Autowired(required=false) 

@Qualifier:与@Autowired一块使用,用于注入类类型属性,并强制使用类的名称注入。其value属性指定要注入类类型属性的类的名称,类的名称则通过组件注解的value属性自定义。

@Resource:用于注入类类型属性,相当于@Autowired和@Qualifier一起使用,默认使用类的名称注入(装配),其name属性指定要注入类类型属性的类的名称,不指定name属性的值则名称默认值为属性名。

  @Resource应用在字段(成员变量)上注入规则是:  

    a.先使用字段名字匹配bean,查找到bean则注入。如果bean中定义的类型与注入的类型不匹配则异常

    b.如果没有指定name属性并且字段名字没有匹配到Bean,则会尝试采用字段类型匹配,如果找到bean则注入。如果字段类型是接口则有可能会匹配到多个类型,会抛出匹配到多个bean的异常

  @Resource应用在setter方法上注入规则是:

    a.先使用setter方法形参参数名匹配bean,如果bean中定义的类型与注入的类型不匹配则异常

    b.如果属性名字没有匹配到Bean,则会尝试采用属性参数类型匹配。如果找到bean则注入,如果属性参数类型是接口则有可能会匹配到多个bean的异常,注入失败。所以,一般采用实现类做为set方法的参数,这也是之所以有字段注入还存在set注入的原因。

理解字段注入和set注入区别的例子:

//接口UserDao
public interface UserDao;
//接口实现1
public class UserDao1 implements UserDao {...};
//接口实现2
public class UserDao2 implements UserDao {...};

//1、采用字段注入,则会注入失败(会出现匹配多个bean的异常)
@Resource
private UserDao userDao;

//2、采用setter方法注入,则可以注入UserDao1
@Resource
public void setUserDao(UserDao1 userDao)
//注入UserDao2 
@Resource
public void setUserDao(UserDao2 userDao)

属性注入注解使用例子:

注意:
@Autowired是属于Spring的注解

@Resource为JSR-250标准的注释,属于J2EE,使用它减少了与spring的耦合,代码看起比较优雅。

4.2.2.3 Bean的作用范围注解

@Scope

默认value属性值为singleton,单例。还可以指定为prototype,多例。

 

4.2.2.4 Bean的生命周期配置注解

@PostConstruct:相当于xml方式的init-method属性
@PreDestroy:相当于xml方式的destroy-method属性

Bean的作用范围必须是单例singleton才能在spring工厂执行close方法时执行@PreDestry注解标注的方法。

@Resource、@PostConstruct、@PreDestroy所属的包是javax.annotation,如果jdk版本过低,比如1.5,这三个注解将无法使用。

4.2.3 使用Java类定义Bean信息(了解)

Spring3.0以JavaConfig为核心,提供以JavaBean作为配置文件方式的开发。

@Configuration
public class BeanConfig {

    @Bean(name="car")
    public Car showCar(){
        Car car = new Car();
        car.setName("兰博基尼");
        car.setPrice(2000000d);
        return car;
    }
    
    @Bean(name="product")
    public Product showProduct(){
        Product product = new Product();
        product.setName("苹果6sp");
        product.setPrice(8500d);
        return product;
    }
}

4.3 Spring的Bean管理方式比较

XML:结构清晰

注解:属性注入,开发方便

实际开发中还有一种XML和注解整合开发:Bean的创建由XML配置,但是属性使用注解注入。

5 Spring整合Web项目

5.1 Spring整合Web项目步骤

步骤一:创建web项目,引入Spring IOC开发包

参考3.1的步骤二。

步骤二:创建包结构 

com.itheima  

  web

    UserServlet

  service

    UserService

  dao

    UserDao

步骤三:创建Spring的配置文件

这里使用xml方式管理Spring中的bean。所以只需要引入bean的约束即可。

<?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">
    
    <!-- 配置Service和DAO到Spring的配置文件中 -->
    <bean id="userService" class="com.itheima.service.UserService">
        <property name="userDao" ref="userDao"/>
    </bean>
    
    <bean id="userDao" class="com.itheima.dao.UserDao"></bean>

</beans>

步骤四:在Servlet中获得Service对象

// 创建工厂
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
        "applicationContext.xml");
//获取Service对象
UserService userService = (UserService) applicationContext
        .getBean("userService");
System.out.println("UserServlet的方法执行了...");
//执行Service对象方法
userService.save();

步骤五:Spring工厂初始化原理及配置

问题:此时访问一次Servlet,就会创建一个Spring的工厂,因而效率很低。

思路1:将Spring工厂的创建放入到Servlet的init方法中。这种方式不好,有多个Servlet的情况,创建一个Servlet就会调用一下init方法创建一个Spring的工厂。

思路2:将Spring工厂创建好以后放入ServletContext域中。使用工厂的时候,从ServletContext中获得。

ServletContextListener接口的实现类是用来监听ServletContext对象的创建和销毁的监听器,Spring的核心监听器ContextLoaderListener实现了ServletContextListener接口:

当ServletContext对象创建的时候,创建spring工厂, 然后将spring工厂存入到ServletContext对象中:

因此,Spring整合Web项目时还需要引入spring-web-3.2.0.RELEASE.jar包,它包含了Spring的核心监听器ContextLoaderListener。

然后还需要在web.xml中配置Spring的核心监听器ContextLoaderListener:

<!-- 配置Spring的核心监听器 -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- 因为该监听器默认是加载WEB-INF目录下的配置文件,所以需要修改参数读取类路径下的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>

步骤六:在Servlet中获得Spring工厂

web.xml中配置servlet:

<servlet>
    <servlet-name>UserServlet</servlet-name>
    <servlet-class>com.itheima.web.UserServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>UserServlet</servlet-name>
    <url-pattern>/userServlet</url-pattern>
</servlet-mapping>

在Servlet中从ServletContext中获得Spring工厂:

方式一:ServletContext.getAttribute(“...”);//参数名太长,不推荐

方式二:WebApplicationContextUtils.getWebApplicationContext(ServletContext context);

5.2 Spring的分配置文件开发

Spring中提供了两种方式加载多个配置文件:

一、主配置文件applicationContext.xml中包含其他的配置文件:

<import resource="applicationContext2.xml"/>

二、工厂创建的时候直接加载多个配置文件:

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "applicationContext.xml","applicationContext2.xml");

实际开发中Spring整合web项目在web.xml中配置spring监听器ContextLoaderListener,并加载spring容器至web容器ServletContext中

<!-- 配置Spring的核心监听器:ContextLoaderListener,实现了ServletContextListener用来监听ServletContext对象(即web容器)的创建和销毁 -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 加载spring容器至web容器中 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <!-- spring的配置文件名称以applicationContext-XXX.xml命名,方便维护 -->
    <!-- Include包含的方式缺陷是每个模块的配置文件都需要手动包含至web.xml中 -->
    <param-value>/WEB-INF/classes/spring/applicationContext.xml,/WEB-INF/classes/spring/applicationContext-*.xml</param-value>
</context-param>

 

6 Spring整合JUnit单元测试

Spring为了简化测试,提供与JUnit的整合,就不需要每次在测试方法中手动创建spring工厂对象。

首先手动添加Junit4的环境:

然后在程序中引入spring-test-3.2.0.RELEASE.jar。

测试类编写:

@RunWith(SpringJUnit4ClassRunner.class)//spring和JUnit整合的核心运行类
@ContextConfiguration("classpath:applicationContext.xml")//spring配置文件路径
public class SpringDemo1 {
    
    @Resource(name="userService")//此时引入了以上jar包之后,不需要开启spring组件扫描配置了
    private UserService userService;
    
    @Test
    public void demo2(){
        userService.save();
    }
}

 

转载于:https://www.cnblogs.com/crxdb/p/6828546.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值