一. 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/>标签。
六.一 先定义一个父类 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>
谢谢!!!