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

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

一. 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环境下。


2019041520050421.png


测试单例:


<!--或者省略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(); //可以
  }


2019041719360578.png


三. 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 下面,还有一些其他的值


20190417194406723.png

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


五 . ApplicationContext 接口


20190417194717702.png


利用多态,常常构建的类是 ClassPathXmlApplicationContext,和FileSystemXmlApplicationContext


其中,ClassPathXmlApplicationContext 是加载类路径下的配置文件

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


20190417195050984.png


其中,有个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>


谢谢!!!

相关文章
|
2月前
|
XML Java 数据格式
Spring从入门到入土(xml配置文件的基础使用方式)
本文详细介绍了Spring框架中XML配置文件的使用方法,包括读取配置文件、创建带参数的构造对象、使用工厂方法和静态方法创建对象、对象生命周期管理以及单例和多例模式的测试。
119 7
Spring从入门到入土(xml配置文件的基础使用方式)
|
1月前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
49 0
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
58 4
|
2月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
41 0
|
2月前
|
Java API Spring
在 Spring 配置文件中配置 Filter 的步骤
【10月更文挑战第21天】在 Spring 配置文件中配置 Filter 是实现请求过滤的重要手段。通过合理的配置,可以灵活地对请求进行处理,满足各种应用需求。还可以根据具体的项目要求和实际情况,进一步深入研究和优化 Filter 的配置,以提高应用的性能和安全性。
|
1月前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
34 1
|
2月前
|
Java BI 调度
Java Spring的定时任务的配置和使用
遵循上述步骤,你就可以在Spring应用中轻松地配置和使用定时任务,满足各种定时处理需求。
154 1
|
2月前
|
XML Java 数据格式
手动开发-简单的Spring基于注解配置的程序--源码解析
手动开发-简单的Spring基于注解配置的程序--源码解析
48 0
|
2月前
|
XML Java 数据格式
手动开发-简单的Spring基于XML配置的程序--源码解析
手动开发-简单的Spring基于XML配置的程序--源码解析
86 0
|
3月前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
244 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)