Spring入门

Spring

一、什么是Spring?

​ Spring是由Rod Johnson组织开发的一个分层轻量级开源框架,以IOC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)为内核,

没学Spring的时候,是这么开发Web项目的:

​ • 1. 实体类—>class User{ }

​ • 2. daoclass–> UserDao{ … 访问db}

​ • 3. service—>class UserService{ UserDao userDao = new UserDao();}

​ • 4. actionclass UserAction{UserService userService = new UserService();}

用户访问:Tomcat->servlet->service->dao

二、Spring可以分为6 大模块:

• Spring Core Spring的核心功能: IOC容器, 解决对象创建及依赖关系

• Spring Web Spring对web模块的支持。

​ – 可以与struts整合,让struts的action创建交给spring

​ – spring mvc模式

• Spring DAO Spring 对jdbc操作的支持 【JdbcTemplate模板工具类】

• Spring ORM spring对orm的支持:

​ – 既可以与hibernate整合,【session】

​ – 也可以使用spring的对hibernate操作的封装

• Spring AOP 切面编程

• SpringEE spring 对javaEE其他模块的支持

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zbzKF6mb-1612319890080)(file:///C:/Users/十里/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg)]

三、Spring的核心容器:

​ Spring容器不单单只有一个,可以归为两种类型

​ • Bean 工厂,BeanFactory 【功能简单】

​ • 应用上下文,ApplicationContext功能强大,一般我们使用这个

​ 1.BeanFactory就是一个管理Bean的工厂,它主要负责初始化各种Bean并调用他们的生命周期方法。

BeanFactory beanFactory=new XmlBeanFactory(new FileSystemResource("D:/applicationContext.xml"));

​ 这种加载方式了解即可。

​ 2.ApplicationContext是BeanFactory的子接口,也被称为上下文,是另一种Spring容器。

​ (1)通过 ClassPathXmlApplicationContext 创建

ApplicationContext ac=new ClassPathXmlApplicationContext(String ConfigLocation);
//configLocation为Spring配置文件的名称和位置。

​ (2) 通过 FileSystemXmlApplicationContext 创建

ApplicationContext ac=new FileSystemXmlApplicationContext(String ConfigLocation);
/*configLocation指定配置文件的位置,如果参数中写的不是绝对路径,那么方法调用的时候,会默认用绝对路径来找。
	采用绝对路径的的方式会是程序的灵活性变差,所以一般不采用。
*/

四、IOC 控制反转

​ Spring的核心思想之一:Inversion of Control , 控制反转 IOC

​ 那么控制反转是什么意思呢???对象的创建交给外部容器完成,这个就叫做控制反转。

​ • Spring使用控制反转来实现,对象不用在程序中写死

​ • 控制反转解决对象处理问题【把对象交给别人创建】

​ 那么对象和对象之间的依赖关系Spring是怎么做的呢??依赖注入:dependency injection.

​ • Spring使用依赖注入来实现对象之间的依赖关系

​ • 在创建完对象之后,对象的关系处理就是依赖注入

​ 上面已经说了,控制反转是通过外部容器完成的,而Spring又为我们提供了这么一个容器,我们一般将这个容器叫做:IOC容器.

无论是创建对象、处理对象之间的依赖关系、对象创建的时间还是对象的数量,我们都是在Spring为我们提供的IOC容器上配置 对象的信息就好了。

知乎:Spring IOC 有什么好处:https://www.zhihu.com/question/23277575/answer/24259844

ioc的思想最核心的地方在于,资源不由使用资源的双方管理,而由不使用资源的第三方管理,这可以带来很多好处。第一,资源集中管理,实现资源的可配置和易管理。第二,降低了使用资源双方的依赖程度,也就是我们说的耦合度。
也就是说,甲方要达成某种目的不需要直接依赖乙方,它只需要达到的目的告诉第三方机构就可以了,比如甲方需要一双袜子,而乙方它卖一双袜子,它要把袜子卖出去,并不需要自己去直接找到一个卖家来完成袜子的卖出。它也只需要找第三方,告诉别人我要卖一双袜子。这下好了,甲乙双方进行交易活动,都不需要自己直接去找卖家,相当于程序内部开放接口,卖家由第三方作为参数传入。甲乙互相不依赖,而且只有在进行交易活动的时候,甲才和乙产生联系。反之亦然。这样做什么好处么呢,甲乙可以在对方不真实存在的情况下独立存在,而且保证不交易时候无联系,想交易的时候可以很容易的产生联系。甲乙交易活动不需要双方见面,避免了双方的互不信任造成交易失败的问题。因为交易由第三方来负责联系,而且甲乙都认为第三方可靠。那么交易就能很可靠很灵活的产生和进行了。这就是ioc的核心思想。生活中这种例子比比皆是,支付宝在整个淘宝体系里就是庞大的ioc容器,交易双方之外的第三方,提供可靠性可依赖可灵活变更交易方的资源管理中心。另外人事代理也是,雇佣机构和个人之外的第三方。

一、在Eclipse中,创建一个名为chapter01的Web项目,将Spring的4个基础包以及commons-logging的JAR包复制到lib目录中,并发布到类路径下。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GGJ2M3q3-1612319890084)(https://raw.githubusercontent.com/lanygemini/MyImage/main/image-20200928082944398.png)]

二、在src目录下,创建一个com.itheima.ioc包,并在包中创建接口UserDao,然后在接口中定义一个say()方法。

        package com.itheima.ioc;
        public interface UserDao {
   			public void say();
        }

三、在com.itheima.ioc包下,创建UserDao接口的实现类UserDaoImpl,该类需要实现接口中的say()方法,并在方法中编写一条输出语句。

 package com.itheima.ioc;
        public class UserDaoImpl implements UserDao {
			public void say() {
                  System.out.println("userDao say hello World !");
 			}
       }

四、在src目录下,创建Spring的配置文件applicationContext.xml,并在配置文件中创建一个id为userDao的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-4.3.xsd"> 
             <bean id="userDao" class="com.itheima.ioc.UserDaoImpl" />
       </beans>

五、在com.itheima.ioc包下,创建测试类TestIoC,并在类中编写main()方法。在main()方法中,需要初始化Spring容器,并加载配置文件,然后通过Spring容器获取userDao实例(即Java对象),最后调用实例中的say()方法。

package com.itheima.ioc;
        import org.springframework.context.ApplicationContext;
        import  org.springframework.context.support.ClassPathXmlApplicationContext;
        public class TestIoC {
               public static void main(String[] args) { 
 	       			ApplicationContext applicationContext = 
	              		new ClassPathXmlApplicationContext("applicationContext.xml"); 
                      	UserDao userDao = (UserDao) applicationContext.getBean("userDao");
 	      				userDao.say();
              }
       }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aMdhrUio-1612319890088)(https://raw.githubusercontent.com/lanygemini/MyImage/main/image-20200928083648186.png)]

​ 可以看到控制台成功输出了UserDaoImpl类中的输出语句,但是在main方法中并没有通过new来创建UserDao接口的实现类对象,而实通过Spring容器来获取的实现类对象。这就是Spring IOC容器的工作机制。

五、DI依赖注入

依赖注入的实现方式:

(1)属性setter方法注入:

Spring容器使用setter方法注入被依赖的实例,通过调用无参构造方法或无参静态工厂方法实例化Bean后,调用该Bean的setter方法,即可实现基于setter方法的依赖注入。

package com.itheima.ioc;
        public class UserServiceImpl implements UserService {
	private UserDao userDao; 
	public void setUserDao(UserDao userDao) {
	         this.userDao = userDao;
	} 
	public void say() { 
	         this.userDao.say();//调用UserDao的say()方法。
	         System.out.println("userService say hello World !");
	}
         }

​ 在配置文件applicationContext.xml中,创建一个id为userService的Bean,该Bean用于实例化UserServiceImpl类的信息,并将 userDao的实例注入到userService中。

        <bean id="userService" class="com.itheima.ioc.UserServiceImpl"> 
                 <property name="userDao" ref="userDao" />
        </bean>
(2)构造方法注入:

​ 指Spring容器使用构造方法注入被依赖的对象,通过带参数的构造方法来实现,每个参数代表一个依赖。

(3)内部bean

我们刚才是先创建userDao对象,再由userService对userDao对象进行引用…我们还有另一种思维:先创建userService,发现userService需要userDao的属性,再创建userDao…我们来看看这种思维方式是怎么配置的:

​ applicationContext.xml配置文件:property节点内置bean节点

  <!--
     1.创建userService,看到有userDao这个属性
     2.而userDao这个属性又是一个对象
     3.在property属性下又内置了一个bean
     4.创建userDao
   -->
   <bean id="userService" class="UserService">
     <property name="userDao">
       <bean id="userDao" class="UserDao"/>
     </property>
   </bean>

测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QLLggo5M-1612319890094)(https://raw.githubusercontent.com/lanygemini/MyImage/main/image-20200928150143683.png)]

我们发现这种思维方式和服务器访问的执行顺序是一样的,但是如果userDao要多次被其他service使用的话,就要多次配置了…

(4)注解方式注入
(5)p命名空间方式注入属性值

p名称控件这种方式其实就是set方法的一种优化,优化了配置而已…p名称空间这个内容需要在Spring3版本以上才能使用…我们来看看:

applicationContext.xml配置文件:使用p名称空间

  <bean id="userDao" class="UserDao"/>
   
   <!--不用写property节点了,直接使用p名称空间-->
   <bean id="userService" class="UserService" p:userDao-ref="userDao"/>

测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4tEX363o-1612319890097)(file:///C:/Users/十里/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg)]

六、Bean的实例化

(1)构造器实例化:

​ 指Spring容器通过Bean对应类中的默认无参构造方法来实例化Bean。

(2)静态工厂实例化:

​ 此方法需要创建一个静态工厂的方法来创建Bean的实例。

​ 1.首先创建MyBeanFactory类,并在类中创建createBean()方法来返回Bean2实例

package com.lany.factory;
public class MyBeanFactory {
	public static UserDao createUserDao(){
		return new UserDaoImpl();
	}
}

​ 2.创建Spring配置文件beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://www.springframework.org/schema/beans" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd ">
<!-- 将静态工厂的创建的实例交与sprig	
	class 静态工厂的全限定类名(包名和类名)
-->
	<bean id="userDaoId" class="com.lany.static_factory.MyBeanFactory" 
						factory-method="createUserDao"></bean>
</beans>

​ 3.测试使用静态工厂方式能否实例化Bean。

package com.lany.factory;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestFactory {
	@Test
	public void run1(){
		//自定义实例工厂
		/*MyBeanFactory myBeanFactory=new MyBeanFactory();
		UserDao userDao=myBeanFactory.createUserDao();
		userDao.say();*/
		
		ApplicationContext ac=new ClassPathXmlApplicationContext("beans5.xml");
		UserDao userDao=ac.getBean("userDaoId",UserDao.class);
		userDao.say();
	}
}
(3)实例工厂实例化

​ 此种方法创建Bean实例采用直接创建Bean实例的方式,在配置文件中通过factory-bean属性指向配置的实例工厂,然后通过factory-method属性确定使用工厂中的哪个方法。

​ 1.创建实例工厂类

package com.lany.factory;

/**
 * 实例工厂
 * @author 十里
 *
 */
public class MyBeanFactory {
	public  UserDao createUserDao(){
		return new UserDaoImpl();
		
	}
}

​ 2.修改配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://www.springframework.org/schema/beans" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd ">

<!-- 创建实例工厂 -->
	<bean id="myBeanFactoryId" class="com.lany.factory.MyBeanFactory"></bean>
	<!-- 获得userDao -->
	<bean id="userDaoId" factory-bean="myBeanFactoryId" factory-method="createUserDao"></bean>

</beans>

​ 3.测试

package com.lany.factory;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestFactory {
	@Test
	public void run1(){
		
		//自定义实例工厂
		/*MyBeanFactory myBeanFactory=new MyBeanFactory();
		UserDao userDao=myBeanFactory.createUserDao();
		userDao.say();*/
		
		ApplicationContext ac=new ClassPathXmlApplicationContext("beans5.xml");
		UserDao userDao=ac.getBean("userDaoId",UserDao.class);
		userDao.say();
	}
}

​ 从控制台输出结果可以看出成功的实例化了Bean。

七、Bean的作用域

通过Spring容器创建一个Bean的实例时,不仅可以完成Bean的实例化,还可以为Bean指定作用域。

​ Spring 4.3中为Bean的实例定义了7种作用域,如下表所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oLAqSSBF-1612319890100)(https://raw.githubusercontent.com/lanygemini/MyImage/main/image-20200928144152669.png)]

singleton作用域:

**singleton是Spring容器默认的作用域,当Bean的作用域为singleton时,Spring容器就只会存在一个共享的Bean实例。**singleton作用域对于无会话状态的Bean(如Dao 组件、Service组件)来说,是最理想的选择。

<bean id="scope" class="com.itheima.scope.Scope" scope="singleton"/>
//使用bean的scope属性来指定bean的作用域。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://www.springframework.org/schema/beans" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd ">
	<bean id="userdaoscope" class="com.lany.scope.UserDaoImpl" scope="singleton"></bean>
</beans>
package com.lany.scope;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test_scope {
	@Test
	public void run1(){
		ApplicationContext ac=new ClassPathXmlApplicationContext("beans_scope.xml");
		UserDao userdao=(UserDao) ac.getBean("userdaoscope");
		UserDao userdao1=(UserDao) ac.getBean("userdaoscope");
		System.out.println(userdao);
		System.out.println(userdao1);
		System.out.println(userdao==userdao1);
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5umR6Z20-1612319890102)(https://raw.githubusercontent.com/lanygemini/MyImage/main/image-20200928144801483.png)]

可以看出两次的输出结果相同,说明Spring容器只创建了一个Scope类的实例。

prototype作用域:

将xml配置文件中的bean的scope属性改为prototype

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-etICN3KO-1612319890104)(https://raw.githubusercontent.com/lanygemini/MyImage/main/image-20200928145221816.png)]

两次的输出结果并不相同,这说明在prototype作用域下,创建了俩个不同的Scope实例。

八、Bean的生命周期

Spring容器可以管理singleton作用域的Bean的生命周期,在此作用域下Spring能够精确的知道该Bean何时被创建,何时初始化完成以及何时被销毁。

对于prototype作用域的Bean,Spring只负责创建,当容器创建了Bean实例后,Bean的实例就交给客户端代码来管理,Spring容器将不再跟踪其生命周期。每次客户端请求prototype作用域的Bean时,Spring容器都会创建一个新的实例,并且不会管那些被配置成prototype作用域的Bean的生命周期。

Spring容器中Bean的生命周期流程如下图所示;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Chg7G5DX-1612319890106)(https://raw.githubusercontent.com/lanygemini/MyImage/main/image-20200928145930221.png)]

九、Bean的装配方式

什么时Bean的装配?

​ Bean的装配可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Spring容器支持多种形式的Bean的装配方式,如基于XML的装配、基于注解(Annotation)的装配和自动装配(其中最常用的是基于注解的装配),本节将主要讲解这三种装配方式的使用。

1、基于xml的装配

基于xml的装配就是依赖注入中对xml进行配置的几种方式:setter方法注入,构造器注入,内部bean,p命名空间。

1.创建Java类,提供有参、无参构造以及属性setter方法;

	 /**
		使用构造注入
			提供带所有参数的有参构造方法
	 */
public User(String username, Integer password, List<String> list) {
	super();
    	this.username = username;
    	this.password = password;
		this.list = list;
      } 
      public User() { super();}
      ......
     /**
     	使用设值注入
        	提供默认无参构造方法
        	为所有属性设置setter方法
     */
      //省略属性setter方法

2.创建Spring配置文件beans5.xml,使用2种方式配置Bean;

      <bean id="user1" class="com.itheima.assemble.User">
	     <constructor-arg index="0" value="tom" />
        ...
      </bean>
          
      <bean id="user2" class="com.itheima.assemble.User">
 	   <property name=“username” value=“张三”  />
        ...
      </bean>
          
  <!-- 使用构造注入方式装配User实例  -->
<bean id="user1" class="com.lany.iteima.User">
	<constructor-arg index="0" value="tom"></constructor-arg>
	<constructor-arg index="1" value="123456"></constructor-arg>
	<constructor-arg index="2" >
		<list>
			<value>"constructorvalue1"</value>
			<value>"constructorvalue2"</value>
		</list>
	</constructor-arg>
</bean> 
    
    <!-- 使用设值注入方式装配User实例 -->
<bean id="user2" class="com.lany.iteima.User">
	<property name="name" value="zhangsan"></property>
	<property name="age" value="11"></property>
    <property>
    	<list>
    		<value>"constructorvalue1"</value>
			<value>"constructorvalue2"</value>
    	</list>
    </property>
</bean>
    /*<constructor-arg>元素用于定义构造方法的参数,index属性表示索引(从0开始),value用于设置注入的值
    *<property>元素用于调用Bean实例中setter方法完成属性赋值,从而完成依赖注入。
    */

3.创建测试类,测试程序

public class XmlBeanAssembleTest {
          public static void main(String[] args) {
 	String xmlPath = "com/itheima/assemble/beans5.xml";
	ApplicationContext applicationContext = 
 			         new ClassPathXmlApplicationContext(xmlPath);
                 System.out.println(applicationContext.getBean("user1"));
                 System.out.println(applicationContext.getBean("user2"));
      }
}

2、基于Annotation的装配

基于XML的装配可能会导致XML配置文件过于臃肿,给后续的维护和升级带来一定的困难。为此,Spring提供了对Annotation(注解)技术的全面支持。

Spring提供了组件扫描,来进行对指定包进行扫描,对拥有注解的类进行实例化等操作。

<!--
    使用注解之前,我们要先导入4+2+aop的jar包
    同时引入约束 beans+context 
-->
<!--组件扫描:Spring容器会扫描这个包里所有类,从类的注解信息中获取Bean的信息-->
    <context:component-scan base-package="com.pngyul.domain"></context:component-scan>  
    </beans>  1234567

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6VtoXAa6-1612319890109)(https://raw.githubusercontent.com/lanygemini/MyImage/main/image-20200928160717825.png)]

Spring从2.0开始引入基于注解的配置方式,并且不断的进行完善。通过注解的方式可以直接在类上定义Bean的信息,非常方便。

@Component注解来对类进行标注,它可以被Spring容器识别,Spring容器将自动将类转换为容器管理的Bean。

//使用@Component注解定义Bean ,和<bean id="user" class="com.cad.domain.User">是等效的。
@Component("account")
public class Account {
    private int id;
    private String name;
    private String money;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getMoney() {
        return money;
    }
    public void setMoney(String money) {
        this.money = money;
    }
    @Override
    public String toString() {
        return "Account [id=" + id + ", name=" + name + ", money=" + money + "]";
    }
}1234567891011121314151617181920212223242526272829

除了@Component外,Spring提供了三个功能和@Component等效的注解。
它们一般用于web项目,对DAO,service,web层进行注解,所以也称为Bean的衍生注解。

  • @Repository:对DAO实现类进行注解
  • @Service:对service实现类进行注解
  • @Controller:对web层Controller实现类进行注解

之所以提供这三个特殊的注解,是为了让注解类本身的用途清晰化,此外,Spring还赋予了一些特殊的功能。我们在项目开发中应该尽量使用这种形式

注解方式配置Bean的作用范围和生命过程方法

通过注解配置的Bean和通过< bean >配置的Bean一样,默认的作用范围都是singleton,Spring为注解配置提供了一个@Scope的注解,显式指定Bean的作用范围。

@Controller("user") 
//指定作用范围为多例prototype
@Scope("prototype")
public class User {
    public void say(){
        System.out.println("hello.word");
    }
}12345678

Spring定义的@PostConstruct和@PreDestroy两个注解相当于bean的init-method和destory-method属性的功能

@Controller("account")
@Scope("prototype")
public class Account {
    public void save() {
        System.out.println("hello.word");
    }

    @PostConstruct
    public void myinit() {
        System.out.println("初始化....");
    }

    @PreDestroy
    public void mydestory() {
        System.out.println("销毁中....");
    }

}123456789101112131415161718

注解方式注入一般类型属性

Spring为我们提供了注解 @value,用于对一般属性注入,可以不用提供set方法

@Value("Tom")
private String nmae;
@Value("22")
private int age;

//它是通过反射的Field赋值,破坏了封装性123456

提供set方法的也可以这样注入

@Value("Tom")
Public void setName(String name){
    this.name = name;
}

//通过set方法赋值,推荐使用.123456

然而在实际开发者中,尽管实际是破坏了对象的封装性,但开发者还是喜欢用第一种方式注入属性

注解方式注入引用类型属性

//会根据类型自动注入
@Autowired  
private UserService userservice;123
//@Autowired可以对类成员变量的set方进行注解。
//对set方法使用注解,UserDao的实例就会被注入进来
@Autowired
public void  setUserdao(UserDao userdao){
     this.userdao=userdao;
}123456

问题:@Autowired默认按类型匹配的方式,在容器中查找匹配的Bean,当有且只有一个匹配的Bean时,Spring将其注入到@Autowired注解的变量中。但是如果容器中有超过一个以上的匹配Bean时,例如有两个UserService类型的Bean,这时就不知道将哪个Bean注入到变量中,就会出现异常

为了解决这个问题,Spring可以通过@Qualifier注解来注入指定Bean的名称。

public class UserAction {
     @Autowired 
     //指定指定Bean的名称
     @Qualifier("userservice")
     private UserService userservice;
 }123456

还有一种更为便捷的注解方式注入属性@Resource,相当于@Autowired 和@Qualifier一起使用

@Resource(name="userservice")
private UserService userservice;12

整合多个Spring配置文件

对于一个大型项目而言,可能有多个XML配置文件,在启动Spring容器时,可以通过一个String数组指定这些配置文件。Spring还允许我们通过< import >标签将多个配置文件引入到一个文件中,进行配置文件的集成,这样启动Spring容器时,就仅需指定这个合并好的配置文件即可。

  • 第一种方式,使用String数组指定所有配置文件
ApplicationContext ac=new ClassPathXmlApplicationContext(new String[]{"bean1.xml","bean2.xml"});1
  • 第二种方式,使用import标签
 //resource属性指定配置文件位置,支持Spring标准的资源路径
 <import resource="classthpath:com/cad/domain/bean1.xml"/>
 <import resource="classthpath:com/cad/domain/bean2.xml"/>123

第一种方式并不容易维护,我们在开发中推荐使用第二种方式。

spring与JUnit整合测试

以前,我们在测试的时候,都要写 ApplicationContext ac=new ClassPathXmlApplicationContext(“applicationContext.xml”),然后再获取bean对象。

现在使用JUnit,可以直接使用注解来配置,不再需要手写代码

例如下面这个例子:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
    @Resource(name="accountService")
    private AccountService as;

    @Test
    public void fun1(){

        as.transfer(1, 2, 100d);
    }
3、自动装配

​ 所谓自动装配,就是将一个Bean自动的注入到到其他Bean的Property中。 Spring的元素中包含一个autowire属性,我们可以通过设置autowire的属性值来自动装配Bean。autowire属性有5个值,其值及说明下表所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q4UHZbor-1612319890112)(https://raw.githubusercontent.com/lanygemini/MyImage/main/image-20200928172030649.png)]

思考:Bean的实例化和依赖注入区别

依赖注入是:一个对象要调用另一个对象时,通常是采用new的方式来创建对象,而Spring的依赖注入是由Spring容器来创建的,Spring容器将依赖对象负责把被依赖的对象赋值给调用者的成员变量,这就相当于依赖注入。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7qJ4HJJA-1612319958438)(https://raw.githubusercontent.com/lanygemini/MyImage/main/image-20200928144152669.png#pic_center)]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值