Spring的applicationContext.xml的配置和lookup-method,replaced-method的使用(三)

本文深入解析Spring框架的配置文件,包括根节点<beans>的属性、<bean>元素的详细配置,如id、class、scope等属性,以及属性值的注入方式。同时,介绍了ApplicationContext接口的使用,lookup-method和replace-method的应用,以及bean间的继承、依赖和引用关系。

东家蝴蝶西家飞,白骑少年今日归。 愿,所有迷茫的人,都不再迷茫的,愿,所有努力工作的人,都可以得到应有的回报,愿,所有的人,都可以找到回家的方向,愿,再无苦痛,再无离别。

上一章简单介绍了Spring的三种创建方式和各种属性的注入(二),如果没有看过,请观看上一章

一. Spring的配置文件常用属性

上一章,简单介绍了applicationContext.xml的一些常用的属性,这里,再继续深入一些。

一.一 根节点 <beans>

Spring配置文件的根节点是beans,由一个又一个的bean 组成。

一.二 beans 下面的属性有一个<description >

这是对整个beans 进行的修饰。

 <description>这个Spring项目的总的配置文件</description> 

一.三 beans下面有一个<alias >

可以为一个bean,起多个不同的别名,但多个别名都共同指向同一个bean,一般用来指定数据源。

<!--起得别名-->
<alias name="person" alias="person1"/>
<alias name="person" alias="person2"/>
<!--真实的bean-->
	<bean id="person" class="com.yjl.pojo.Person">

那么在调用的时候,

// 两个person1,peson2 都可以取得同样的一个bean,即com.yjl.pojo.Person对象
Person person=(Person) applicationContext.getBean("person1");
Person person=(Person) applicationContext.getBean("person2");

一.四 beans下有一个 <import >

合作开发的时候,或者是一个applicationContext.xml中的内容按照不同模块进行分开的时候,常用到这个属性,表示引入其他的配置文件。
如在applicationContext.xml中引入,1,2,3.xml文件

<!-- 可以引入多个,注意目录地址,ctrl+鼠标可以点进去查看 -->
	 <import resource="applicationContext1.xml"/>
    <import resource="applicationContext2.xml"/>
    <import resource="applicationContext3.xml"/>

这样在引用的时候,就可以直接传入一个文件名即可。

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

当然,也可以分开写,不用import 引用,在创建时,传入多个参数

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

在与Strut2或者是SpringMVC进行整合的时候,可以利用 * 进行相应的引入。
这是beans 下面的。

二. < bean> 下面的属性

其中,bean 下面最主要使用的只有三个属性, id, class,scope.

二.一 id属性

id属性是唯一的,不能重复的,就是通过id来得到其对应的class,然后反射创建对象。
如果引入了多个文件,那么id 也是不能重复的。 是类似jsp的静态的引入。

二.二 class属性

要创建对象的全限定类名称, 必须要引入全。 这样可以利用反射来创建相应的对象。

Class.forName("class的全限定名称");

其中,这个类必须要有空构造方法。

二.三 name属性

name属性相当于id属性,当不存在id属性的时候,也是可以通过name 属性来取得的。
但一般还是建议使用id

二.四 scope属性

作用范围,其取值有五种, single 单例,默认是单例的, prototype 多例, request 请求域,session session作用域 globalSession 运用于Prolet环境中, request,session,globalSession 是用于Web环境下。
在这里插入图片描述
测试单例:

<!--或者省略scope-->
<bean id="person1" class="com.yjl.pojo.Person" scope="singleton">
    </bean>
@Test
	public void test1(){
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
		Person p1=applicationContext.getBean("person1",Person.class);
		Person p2=applicationContext.getBean("person1",Person.class);
		System.out.println("p1=p2:"+(p1==p2)); //true
	}

测试多例:

<bean id="person2" class="com.yjl.pojo.Person" scope="prototype">
    </bean>
@Test
	public void test2(){
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
		Person p1=applicationContext.getBean("person2",Person.class);
		Person p2=applicationContext.getBean("person2",Person.class);
		System.out.println("p1=p2:"+(p1==p2)); //false
	}

二.五 depends-on 依赖

两个有固定实例化关系的类,如父类和子类,必须先实例化父类,才能实例化子类,或者有一定先后顺序的两个类, 可以利用depends-on . 表示想实例化这个类之前,必须先实例化那个类。
如:

<bean id="userEL3" class="com.yjl.pojo.User" depends-on="carEL1">
		<property name="name" value="#{carEL1.name}"></property>
		<property name="description" value="#{carEL1.description}"></property>
		<property name="car" value="#{carEL1}"></property>
	</bean>
	<bean id="carEL1" class="com.yjl.pojo.Car">
		<property name="name" value="#{'牛车4'}"></property>
		<property name="description" value="#{'一辆虽破却不丑的车4'}"></property>
	</bean>

在实例化User 类之前,必须先实例化Car 类。

二.六 lazy-init 懒加载

有时候,有些bean 可能是用不到的,但又不保证一定用不到,所以可以在用到的时候才进行相应的初始化,可以进行相应的懒加载操作。 有true,false,default 三个值。 默认是default.

二.七 factory-bean

表示指定的是哪个工厂实例对象

二.八 factory-method

表示指定哪个工厂方法

这两个使用,可以参照第二章的Spring的三种创建方式的第二种和第三种方式。

二.九 init-method 和destroy-method

init-method表示创建这个Bean时所要调用的方法,destroy-method 表示销毁或者关闭这个bean时所要调用的方法
如在Person类中创建两个方法:

/**
	 * 定义初始化时的方法
	 * @author yuejl
	 * @Description 定义初始化时的方法
	 */
	public void initPerson(){
		System.out.println("初始化person");
	}
	/**
	 * 
	 * @author yuejl
	 * @Description 定义销毁时的方法
	 */
	public void destroyPerson(){
		System.out.println("销毁person");
	}

在创建person 的bean时,进行相应的引用

<!-- 必须使用的scope是单例范围 -->
<bean id="person4" class="com.yjl.pojo.Person"
     init-method="initPerson" destroy-method="destroyPerson">
    </bean>

测试方法:

@Test
	public void test4(){
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
		Person p1=applicationContext.getBean("person4",Person.class);
		//关闭销毁的时候,这四种方式都可以。
		 //((ClassPathXmlApplicationContext)applicationContext).destroy(); //可以
		//((ClassPathXmlApplicationContext)applicationContext).close(); //可以
		//((AbstractApplicationContext)applicationContext).registerShutdownHook(); //可以
		((AbstractApplicationContext)applicationContext).close(); //可以
	}

在这里插入图片描述

三. bean下的各种属性的值

三.一 <constructor-arg>

	<constructor-arg index="" 
		name=""  type="" value="" ref=""> 
		</constructor-arg>

为构造方法注入,其中 index 表示索引的位置 ,从0开始, name 表示属性的名称, type表示类型,用全限定名称的Java类型,如 int 用 java.lang.Integer, String 用java.lang.String , value 指定的是具体的普通值, ref 引用的是bean.

三.二 <property >

<property name="" value="" ref=""></property>

name 指定的属性名称, value 表示普通的值, ref 为引用bean

三.三 <description >

对当前的bean 进行相应的描述

<description>这是实例化人的Bean</description>

三.四 lookup-method 见下文

三.五 replaced-method 见下文

四 其他值

在properties 和constructor-arg 下面,还有一些其他的值

在这里插入图片描述
array,表示属性是数组,description 表示对这个属性的描述,list 表示属性是list集合,map 表示属性是map,null 表示引用空值 props表示为属性文件 ref 表示引用哪个bean, set 为set属性 ,不常用,具体可以参照第二章,各种属性的注入。

五 . ApplicationContext 接口

在这里插入图片描述
利用多态,常常构建的类是 ClassPathXmlApplicationContext,和FileSystemXmlApplicationContext
其中,ClassPathXmlApplicationContext 是加载类路径下的配置文件
FileSystemXmlApplicationContext 是加载本地磁盘下的配置文件
在这里插入图片描述
其中,有个BeanFactory.
其中,BeanFactory 是在getBean() 时才会生成的类的实例
而ApplicationContext 是在加载 applicationContext.xml文件时就会生成.

六. lookup-method 的使用

假设一个单例模式的bean A需要引用另外一个非单例模式的bean B,为了在我们每次引用的时候都能拿到最新的bean B,我们可以让bean A通过实现ApplicationContextWare来感知applicationContext(即可以获得容器上下文),从而能在运行时通过ApplicationContext.getBean(String beanName)的方法来获取最新的bean B。但是如果用ApplicationContextAware接口,就让我们与Spring代码耦合了,违背了反转控制原则(IoC,即bean完全由Spring容器管理,我们自己的代码只需要用bean就可以了)。

所以Spring为我们提供了方法注入的方式来实现以上的场景。方法注入方式主要是通过<lookup-method/>标签。
以上文字引用于: https://www.cnblogs.com/ViviChan/p/4981619.html

六.一 先定义一个父类 Animal.java

public class Animal {
	public Animal(){
		System.out.println("抽象的动物");
	}
}

有两个子类 Dog.java 和Cat.java

六.二 Dog.java

public class Dog extends Animal {

	public Dog() {
		System.out.println("这是一个狗");
	}
	
}

六.三 Cat.java

public class Cat extends Animal {
	public Cat(){
		System.out.println("这是一个猫");
	}
}

六.四 有一个实现的工厂AnimalFactory,来得到父类对象引用

package com.yjl.factory;

import com.yjl.pojo.Animal;

/**
 @author:yuejl
 @date: 2019年4月17日 下午3:34:09
 @Description 类的相关描述
*/
public abstract class AnimalFactory {
	//得到动物的工厂方法
	public abstract Animal getAnimal();
}

这样,配置文件可以这么写:

六.五 配置文件

<!--必须是多例的-->
 <bean id="dog" class="com.yjl.pojo.Dog" scope="prototype"></bean>
    <bean id="cat" class="com.yjl.pojo.Cat" scope="prototype"></bean>
    <!--工厂是单例的-->
    <bean id="dogFactory" class="com.yjl.factory.AnimalFactory">
    	<!--name指定方法,bean为引用的对象-->
    	<lookup-method name="getAnimal" bean="dog"/>
    </bean>
    <bean id="catFactory" class="com.yjl.factory.AnimalFactory">
    	<lookup-method name="getAnimal" bean="cat"/>
    </bean>

六.六 测试方法

@Test
	public void test5(){
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
		AnimalFactory animalFactory=(AnimalFactory) applicationContext.getBean("dogFactory");
		Animal animal1=animalFactory.getAnimal();
		Animal animal2=animalFactory.getAnimal();
		System.out.println("animal1=animal2:"+(animal1==animal2)); //为false, 每次都是最新的bean
	}

七 replace-method 的使用

主要作用就是替换方法体及其返回值。

七.一 创建普通的bean 对象

package com.yjl.pojo;
/**
 @author:yuejl
 @date: 2019年4月17日 下午3:49:43
 @Description 类的相关描述
*/
public class Hello {
	public void say(){
		System.out.println("两个蝴蝶飞,你好");
	}
}

七.二 创建替换的类

需要实现 MethodReplace接口

package com.yjl.pojo;

import java.lang.reflect.Method;

import org.springframework.beans.factory.support.MethodReplacer;

/**
 @author:yuejl
 @date: 2019年4月17日 下午3:50:17
 @Description 需要实现MethodReplacer的接口
*/
public class ReplaceHello implements MethodReplacer{
	//要替换的对象, 方法,和参数
	@Override
	public Object reimplement(Object arg0, Method arg1, Object[] arg2) throws Throwable {
		System.out.println("你好,世界");
		return arg0;
	}

}

七.三 创建xml

 <!-- 要替换的类 -->
    <bean id="replaceHello" class="com.yjl.pojo.ReplaceHello"></bean>
    <!-- 普通的类 -->
    <bean id="hello" class="com.yjl.pojo.Hello">
    	<!-- name 指明要替换的方法, replacer 指明要替换的是哪个类 -->
    	<replaced-method name="say" replacer="replaceHello"></replaced-method>
    </bean>

七.四 测试方法

@Test
	public void test6(){
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
		Hello hello=applicationContext.getBean("hello",Hello.class);
		// 不加入replaced-method 输出两个蝴蝶飞,加入之后,输出你好,世界
		hello.say(); //两个蝴蝶飞     // 你好,世界
	}

八 类bean 之间的关系

类Bean 之间有三种关系

八.一 继承

第一种为继承,利用abstract=“true” 来确定,父类要设置abstract=“true”,子类要设置 parent =“父类的bean id” .

	<bean id="abstractPeople" class="com.java1234.entity.People" abstract="true">
		<property name="className" value="高三5班"></property>
		<property name="age" value="19"></property>
	</bean>
	
	<bean id="zhangsan" parent="abstractPeople" >
		<property name="id" value="1"></property>
		<property name="name" value="张三"></property>
	</bean>

八.二 依赖

利用depends-on 来进行依赖,在生成这个类Bean 之前,先生成依赖的那个bean.

<bean id="zhangsan" parent="abstractPeople" depends-on="autority">
		<property name="id" value="1"></property>
		<property name="name" value="张三"></property>
	</bean>
<bean id="autority" class="com.java1234.service.Authority"></bean>

八.三 引用

以前常见的例子,一个类中属性是其他类的引用。

<bean id="dog" class="com.java1234.entity.Dog">
		<property name="name" value="jack"></property>
	</bean>
	<bean id="lisi" parent="abstractPeople">
		<property name="id" value="2"></property>
		<property name="name" value="李四"></property>
		<property name="age" value="20"></property>
		<property name="dog" ref="dog"></property>
	</bean>

谢谢!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两个蝴蝶飞

你的鼓励,是老蝴蝶更努力写作的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值