东家蝴蝶西家飞,白骑少年今日归。 愿,所有迷茫的人,都不再迷茫的,愿,所有努力工作的人,都可以得到应有的回报,愿,所有的人,都可以找到回家的方向,愿,再无苦痛,再无离别。
上一章简单介绍了Spring的三种创建方式和各种属性的注入(二),如果没有看过,请观看上一章
上一章,简单介绍了applicationContext.xml的一些常用的属性,这里,再继续深入一些。
Spring配置文件的根节点是beans,由一个又一个的bean 组成。
这是对整个beans 进行的修饰。
这个Spring项目的总的配置文件
可以为一个bean,起多个不同的别名,但多个别名都共同指向同一个bean,一般用来指定数据源。
那么在调用的时候,
// 两个person1,peson2 都可以取得同样的一个bean,即com.yjl.pojo.Person对象
Person person=(Person) applicationContext.getBean("person1");
Person person=(Person) applicationContext.getBean("person2");
合作开发的时候,或者是一个applicationContext.xml中的内容按照不同模块进行分开的时候,常用到这个属性,表示引入其他的配置文件。
如在applicationContext.xml中引入,1,2,3.xml文件
这样在引用的时候,就可以直接传入一个文件名即可。
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
当然,也可以分开写,不用import 引用,在创建时,传入多个参数
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml,applicationContext1.xml,
applicationContext2.xml,applicationContext3.xml");
在与Strut2或者是SpringMVC进行整合的时候,可以利用 * 进行相应的引入。
这是beans 下面的。
其中,bean 下面最主要使用的只有三个属性, id, class,scope.
id属性是唯一的,不能重复的,就是通过id来得到其对应的class,然后反射创建对象。
如果引入了多个文件,那么id 也是不能重复的。 是类似jsp的静态的引入。
要创建对象的全限定类名称, 必须要引入全。 这样可以利用反射来创建相应的对象。
Class.forName("class的全限定名称");
其中,这个类必须要有空构造方法。
name属性相当于id属性,当不存在id属性的时候,也是可以通过name 属性来取得的。
但一般还是建议使用id
作用范围,其取值有五种, single 单例,默认是单例的, prototype 多例, request 请求域,session session作用域 globalSession 运用于Prolet环境中, request,session,globalSession 是用于Web环境下。
测试单例:
@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
}
测试多例:
@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 . 表示想实例化这个类之前,必须先实例化那个类。
如:
在实例化User 类之前,必须先实例化Car 类。
有时候,有些bean 可能是用不到的,但又不保证一定用不到,所以可以在用到的时候才进行相应的初始化,可以进行相应的懒加载操作。 有true,false,default 三个值。 默认是default.
表示指定的是哪个工厂实例对象
表示指定哪个工厂方法
这两个使用,可以参照第二章的Spring的三种创建方式的第二种和第三种方式。
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时,进行相应的引用
测试方法:
@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(); //可以
}
为构造方法注入,其中 index 表示索引的位置 ,从0开始, name 表示属性的名称, type表示类型,用全限定名称的Java类型,如 int 用 java.lang.Integer, String 用java.lang.String , value 指定的是具体的普通值, ref 引用的是bean.
name 指定的属性名称, value 表示普通的值, ref 为引用bean
对当前的bean 进行相应的描述
这是实例化人的Bean
在properties 和constructor-arg 下面,还有一些其他的值
array,表示属性是数组,description 表示对这个属性的描述,list 表示属性是list集合,map 表示属性是map,null 表示引用空值 props表示为属性文件 ref 表示引用哪个bean, set 为set属性 ,不常用,具体可以参照第二章,各种属性的注入。
利用多态,常常构建的类是 ClassPathXmlApplicationContext,和FileSystemXmlApplicationContext
其中,ClassPathXmlApplicationContext 是加载类路径下的配置文件
FileSystemXmlApplicationContext 是加载本地磁盘下的配置文件
其中,有个BeanFactory.
其中,BeanFactory 是在getBean() 时才会生成的类的实例
而ApplicationContext 是在加载 applicationContext.xml文件时就会生成.
假设一个单例模式的bean A需要引用另外一个非单例模式的bean B,为了在我们每次引用的时候都能拿到最新的bean B,我们可以让bean A通过实现ApplicationContextWare来感知applicationContext(即可以获得容器上下文),从而能在运行时通过ApplicationContext.getBean(String beanName)的方法来获取最新的bean B。但是如果用ApplicationContextAware接口,就让我们与Spring代码耦合了,违背了反转控制原则(IoC,即bean完全由Spring容器管理,我们自己的代码只需要用bean就可以了)。
所以Spring为我们提供了方法注入的方式来实现以上的场景。方法注入方式主要是通过
以上文字引用于: https://www.cnblogs.com/ViviChan/p/4981619.html
public class Animal {
public Animal(){
System.out.println("抽象的动物");
}
}
有两个子类 Dog.java 和Cat.java
public class Dog extends Animal {
public Dog() {
System.out.println("这是一个狗");
}
}
public class Cat extends Animal {
public Cat(){
System.out.println("这是一个猫");
}
}
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();
}
这样,配置文件可以这么写:
@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
}
主要作用就是替换方法体及其返回值。
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;
}
}
@Test
public void test6(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
Hello hello=applicationContext.getBean("hello",Hello.class);
// 不加入replaced-method 输出两个蝴蝶飞,加入之后,输出你好,世界
hello.say(); //两个蝴蝶飞 // 你好,世界
}
类Bean 之间有三种关系
第一种为继承,利用abstract=“true” 来确定,父类要设置abstract=“true”,子类要设置 parent =“父类的bean id” .
利用depends-on 来进行依赖,在生成这个类Bean 之前,先生成依赖的那个bean.
以前常见的例子,一个类中属性是其他类的引用。
谢谢!!!