Spring文档笔记一(配置、初始化与依赖注入)

Spring文档笔记一(配置、初始化与依赖注入)

1.1
*配置Spring容器外的对象

可以使用Spring与AspectJ的集成来配置在IoC容器的控制范围之外创建的对象。请参阅使用AspectJ与Spring依赖注入域对象

实际工作中,我们经常会想new一个Bean,然后在这个Bean中注入Spring管理的其他Bean。但是new出来的bean已经脱离Spring的管控了。

// preConstruction 表示在构造函数前注入
@Configurable(autowire= Autowire.BY_NAME, preConstruction = true)
public class Account { 
    private String name; 
    @Autowired
    private BeanA beanA;  
    /**
    *gets sets
    **/
}

Account accountA=new Account();  //会自动注入beanA
组合多个xml文件
<beans>
        <import resource="services.xml"/>
        <import resource="resources/messageSource.xml"/>
        <import resource="/resources/themeSource.xml"/>

        <bean id="bean1" class="..."/>
        <bean id="bean2" class="..."/>
</beans>

路径的一点小提示

可以但**不建议使用 ** 相对的“ …/”路径引用父目录中的文件。这样做会创建对当前应用程序外部文件的依赖。特别是,不建议对“ classpath:” URL(例如,“ classpath:…/ services.xml”)URL使用此引用,在URL中,运行时解析过程会选择“最近的”类路径根,然后查看其父目录。类路径配置的更改可能导致选择其他错误的目录。

您始终可以使用标准资源位置而不是相对路径:例如,“ file:C:/config/services.xml”或“ classpath:/config/services.xml”。但是,请注意,您正在将应用程序的配置耦合到特定的绝对位置。通常最好对这样的绝对位置保留一个间接寻址,例如通过在运行时针对JVM系统属性解析的“ $ {…}”占位符。

*1.3Bean的 概述

在容器本身中,这些bean定义表示为BeanDefinition对象,其中包含(其他信息)以下元数据

  • 全类名:class属性

  • Bean行为配置元素 : scope, lifecycle callbacks, 等等

  • ref : 对其他bean的引入 ,也称为 依赖 或者 合作

  • 要在新创建的对象中设置的其他配置设置,例如,要在管理连接池的bean中使用的连接数,或池的大小限制

PropertyExplained in…
classInstantiating beans
nameNaming beans
scopeBean scopes
constructor argumentsDependency Injection
propertiesDependency Injection
autowiring modeAutowiring collaborators
lazy-initialization modeLazy-initialized beans
initialization methodInitialization callbacks
destruction methodDestruction callbacks

ApplicationContext实现还允许注册在容器外部创建的现有对象

通过**getBeanFactory()**方法访问ApplicationContext的BeanFactory来完成的,该方法返回BeanFactory实现类DefaultListableBeanFactory,

DefaultListableBeanFactory通过**registerSingleton(…)和registerBeanDefinition(…)**方法支持这种注册。

但是,典型的应用程序只使用通过元数据bean定义定义的bean。

Bean元数据和手动提供的单例实例需要尽早注册,以便容器在自动装配和其他自省步骤中正确地推理它们。虽然在某种程度上支持覆盖现有元数据和现有单例实例,但未正式支持在运行时(与对工厂的实时访问同时)对新bean的注册,并且可能导致bean容器中的并发访问异常和/或状态不一致。

😢虽然不是很懂后面一句话说的意思

bean的name

如果不设置name,那么

  • 第一个字母小写的驼峰命名法 如 UserService -》 userService
  • 如果前两个字母都是大写 则和类名一致 如 USerService -》USerService

bean的别名

在大型系统上可能不同的子系统使用不同的别名便于管理和阅读
<alias name="subsystemA-dataSource" alias="subsystemB-dataSource"/>
<alias name="subsystemA-dataSource" alias="myApp-dataSource" />
bean的初始化

在XML中会指定class属性,这个属性会保存在 BeanDefinition 中 ,有两个用途:

  • 通过构造函数构造对象 如同new
  • 类中含有静态工厂方法,用来调用。 方法返回的不一定要是同一个类

如果希望为静态内部类配置bean class属性应该为 com.example.Foo$Bar Bar是Foo的静态内部类

构造函数初始化

Spring IoC容器几乎可以管理您想要它管理的任何类。 它不仅限于管理真正的JavaBean。 大多数Spring用户更喜欢实际的JavaBean,它们仅具有默认(无参数)构造函数,并具有根据容器中的属性建模的适当的setter和getter。 您还可以在容器中具有更多奇特的非bean样式类。 例如,如果您需要使用绝对不符合JavaBean规范的旧式连接池,则Spring也可以对其进行管理。

提供一个空的构造函数 当然也可以用有参构造函数 (需要提供参数)

<bean id="exampleBean" class="examples.ExampleBean"/>

<bean name="anotherExample" class="examples.ExampleBeanTwo"/>

静态工厂初始化

<bean id="clientService"
        class="examples.ClientService"
        factory-method="createInstance"/>
public class ClientService {
        private static ClientService clientService = new ClientService();
        private ClientService() {}
		//也可以提供参数
        public static ClientService createInstance() {
                return clientService;
        }
}

实例工厂初始化

去掉class属性,使用factory method 和factory bean

一个实例工厂可以提供多个bean的初始化方法

<!-- the factory bean, which contains a method called createInstance() -->
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
        <!-- inject any dependencies required by this locator bean -->
</bean>

<!-- the bean to be created via the factory bean -->
<bean id="clientService"
        factory-bean="serviceLocator"
        factory-method="createClientServiceInstance"/>
public class DefaultServiceLocator {

        private static ClientService clientService = new ClientServiceImpl();

        public ClientService createClientServiceInstance() {
                return clientService;
        }
}

在Spring文档中,factory bean指的是在Spring容器中配置的bean,它将通过实例或静态工厂方法创建对象。相反,FactoryBean(注意大小写)指的是特定于spring的FactoryBean。

1.4依赖注入(DI)

依赖项注入(DI)是一个对象定义其依赖项(即与之一起工作的其他对象)的过程 , 只能通过构造函数参数,传递参数给工厂方法,在构造完成或工厂方法返回对象实例之后设置对象实例的属性

当创建bean时容器再将这些依赖对象注入进去。这个过程从根本上颠倒了bean本身通过直接构建类或通过一种机制例如服务定位模式来控制依赖对象的实例化或定位,因此命名为控制反转(IoC)

依赖注入,减少了程序耦合。加快了开发效率。 Bean不需要去寻找依赖项,不需要知道依赖项的位置或者类 ,这样单元测试变得更加简单。

DI存在两个主要模式,基于构造函数的依赖注入基于Setter的依赖注入

基于构造函数的依赖注入

构造函数参数会去匹配传过来的参数类型,当参数不混淆的时候,按照传参的顺序传入。


public class Foo {

        public Foo(Bar bar, Baz baz) {
                // ...
        }
}

当参数不混淆的时候,不需要传入参数的位置索引和类型。

<beans>
        <bean id="foo" class="x.y.Foo">
                <constructor-arg ref="bar"/>
                <constructor-arg ref="baz"/>
        </bean>

        <bean id="bar" class="x.y.Bar"/>

        <bean id="baz" class="x.y.Baz"/>
</beans>

当引用另一个bean时,类型是已知的,并且可以发生匹配(与前面的示例一样)。 当使用简单类型(例如 true </ value>)时,Spring无法确定值的类型,因此在没有帮助的情况下无法按类型进行匹配。 考虑以下类别:

public class ExampleBean {

        // Number of years to calculate the Ultimate Answer
        private int years;

        // The Answer to Life, the Universe, and Everything
        private String ultimateAnswer;

        public ExampleBean(int years, String ultimateAnswer) {
                this.years = years;
                this.ultimateAnswer = ultimateAnswer;
        }
}

这时可以注明类型

<bean id="exampleBean" class="examples.ExampleBean">
        <constructor-arg type="int" value="7500000"/>
        <constructor-arg type="java.lang.String" value="42"/>
</bean>

也可使用索引 除了解决多个简单值的模糊性之外,指定索引还解决了构造函数具有相同类型的两个参数时的模糊性。注意,索引是基于0的。

<bean id="exampleBean" class="examples.ExampleBean">
        <constructor-arg index="0" value="7500000"/>
        <constructor-arg index="1" value="42"/>
</bean>

还可以使用名称

<bean id="exampleBean" class="examples.ExampleBean">
        <constructor-arg name="years" value="7500000"/>
        <constructor-arg name="ultimateAnswer" value="42"/>
</bean>

请记住,要开箱即用,必须在启用调试标志的情况下编译代码,以便Spring可以从构造函数中查找参数名称。如果您无法使用调试标志(或不想这样做)来编译代码,则可以使用 @ConstructorProperties JDK注释显式命名构造函数参数。然后,样本类必须如下所示:


public class ExampleBean {

        // Fields omitted

        @ConstructorProperties({"years", "ultimateAnswer"})
        public ExampleBean(int years, String ultimateAnswer) {
                this.years = years;
                this.ultimateAnswer = ultimateAnswer;
        }
}

启用调试标志 😩又不懂了可能是自动检测匹配问题叭

就是 javac -g

javac - Java programming language compiler 找-g

maven的话用这个Apache Maven Compiler Plugin

基于setter的依赖注入

基于设置器的 DI是通过在调用无参数构造函数或无参数static工厂方法以实例化您的bean 之后,在您的bean上调用setter方法来完成的。

*基于构造函数还是Setter?

由于您可以混合使用基于构造函数和基于setter的DI,所以对于强制依赖项使用构造函数,对于可选依赖项使用setter方法或配置方法,这是一个很好的经验法则。注意,可以使用setter方法上的@Required注释使属性成为必需的依赖项。

首先spring团队建议使用构造函数依赖注入能保证对象不可变以及保证所有成员变量都注入。

此外,注入构造函数的组件总是以完全初始化的状态返回给客户机(调用)代码。

附带说明一下,大量的构造函数参数是一种不好的代码味道,这暗示着类可能有太多的责任,应该对其进行重构,以更好地解决问题的适当分离。

Setter注入应该主要用于可选的依赖项,这些依赖项可以在类中分配合理的默认值。

否则,应该在依赖注入的任何地方检查成员变量不为null。

Setter注入的唯一好处就是,在对象创建完成后 能够再次配置 或者重新注入

因此,通过JMX MBean进行管理是用于setter注入的非常好的的用例。

😄暂时没用到这个东西先不了解

依赖注入过程

容器执行bean依赖项解析,如下所示:

  • 使用ApplicationContext描述所有bean的配置元数据创建和初始化。可以通过XML,Java代码或注释指定配置元数据。

  • 对于每个bean,其依赖项都以属性,构造函数参数或static-factory方法的参数(如果您使用的是常规构造函数)的形式表示。在实际创建 Bean 时,会将这些依赖项提供给Bean 。

  • 每个属性或构造函数参数都是要设置的值的实际定义,或者是对容器中另一个bean的引用。

  • 每个属性值 或构造函数参数都从其指定的格式转换为该属性或构造函数参数的实际类型。默认情况下,Spring可以将以字符串格式提供的值转换为所有内置类型,如int、long、string、boolean等。

    在创建容器时,Spring容器会验证每个bean的配置。但是,只有在实际创建 Bean之前,才会设置Bean属性本身。创建容器时,将创建具有单例作用域并设置为预先实例化(默认)的Bean。范围在Bean范围中定义。否则,仅在请求时才创建Bean。创建和分配bean的依赖及其依赖的依赖(依此类推)时,创建bean可能会导致创建一个bean图。 这些依赖项之间的分辨率不匹配可能会显示得较晚,即在第一次创建受影响的bean时。

*循环依赖

循环依赖

如果主要使用构造函数注入,则可能会创建无法解决的循环依赖方案。

例如:A类通过构造函数注入需要B类的实例,而B类通过构造函数注入需要A类的实例。如果您将A类和B类的bean配置为相互注入,则Spring IoC容器会在运行时检测到此循环引用,并抛出 BeanCurrentlyInCreationException

一种可能的解决方案是编辑某些类的源代码,这些类的源代码由设置者而不是构造函数来配置。或者,避免构造函数注入,而仅使用setter注入。换句话说,尽管不建议这样做,但是您可以使用setter注入配置循环依赖项。

默认情况下,容器初始化时就会初始化单例对象,如果单例对象依赖有问题就会报错。

而如果设置延迟加载,则会在使用的时候报错。

如果不存在循环依赖,则在注入前会初始化完成依赖bean

<bean id="theTargetBean" class="..."/>

<bean id="theClientBean" class="...">
        <property name="targetName">
            <!--   idref指向的bean在容器部署时会验证bean是否存在 -->
                <idref bean="theTargetBean"/>
        </property>
</bean>
   <!--  上下写法等价,不过上面的多一个验证功能 -->
<bean id="theTargetBean" class="..." />

<bean id="client" class="...">
        <property name="targetName" value="theTargetBean"/>
</bean>
基于静态工厂注入
<bean id="exampleBean" class="examples.ExampleBean" factory-method="createInstance">
        <constructor-arg ref="anotherExampleBean"/>
        <constructor-arg ref="yetAnotherBean"/>
        <constructor-arg value="1"/>
</bean>

<bean id="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
public class ExampleBean {

        // a private constructor
        private ExampleBean(...) {
                ...
        }

        //可以不返回和当前类相同的bean
        public static ExampleBean createInstance (
                AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) { 
                ExampleBean eb = new ExampleBean (...);
                // some other operations...
                return eb;
        }
}

ref元素是或定义元素内的最后一个元素。 范围和验证取决于您是通过 Beanlocalparent 属性指定其他对象的ID /名称

<ref bean="someBean"/>
parent

通过parent属性指定目标bean将创建对当前容器的父容器中的bean的引用。父属性的值可以与目标bean的id属性相同,也可以与目标bean的name属性中的一个值相同,并且目标bean必须位于当前bean的父容器中。

<!-- in the parent context -->
<bean id="accountService" class="com.foo.SimpleAccountService">
        <!-- insert dependencies as required as here -->
</bean>
<!-- in the child (descendant) context -->
<bean id="accountService" <!-- bean name is the same as the parent bean -->
        class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target">
                <ref parent="accountService"/> <!-- notice how we refer to the parent bean -->
        </property>
        <!-- insert other configuration and dependencies as required here -->
</bean>
集合注入

Spring容器还支持集合的合并。应用程序开发人员可以定义一个父风格,,或元素,并有孩子式的,,或元素继承和父集合覆盖值。也就是说,子集合的值是合并父集合和子集合的元素的结果,子集合的元素将覆盖父集合中指定的值。

注意,在bean定义的merge=true属性的props元素 上使用了属性。当容器解析并实例化bean时,结果实例具有一个集合,该集合包含子项的集合与父项的集合合并的结果 。

<beans>
        <bean id="parent" abstract="true" class="example.ComplexObject">
                <property name="adminEmails">
                        <props>
                                <prop key="administrator">administrator@example.com</prop>
                                <prop key="support">support@example.com</prop>
                        </props>
                </property>
        </bean>
        <bean id="child" parent="parent">
                <property name="adminEmails">
                        <!-- the merge is specified on the child collection definition -->
                        <props merge="true">
                                <prop key="sales">sales@example.com</prop>
                                <prop key="support">support@example.co.uk</prop>
                        </props>
                </property>
        </bean>
<beans>

元素的特定情况下,与List集合类型关联的语义(即ordered 值集合的概念)得以保留;父级的值先于子级列表的所有值。

<null/>元素处理null的值。例如:

<bean class="ExampleBean">
        <property name="email">
                <null/>
        </property>
</bean>

上面的配置等效于以下Java代码:

exampleBean.setEmail(null)
depends-on

如果一个bean是另一个bean的依赖项,则通常意味着将一个bean设置为另一个bean的属性。通常,您可以使用基于XML的配置元数据中的<ref/> 元素来完成此操作。但是,有时bean之间的依赖性不太直接。例如,需要触发类中的静态初始化器,例如数据库驱动程序注册。该depends-on属性可以在初始化使用此元素的bean之前显式强制初始化一个或多个bean。以下示例使用该depends-on属性表示对单个bean的依赖关系:

<bean id="beanOne" class="ExampleBean" depends-on="manager"/>
<bean id="manager" class="ManagerBean" />
懒加载bean
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>

然而,当延迟初始化的bean是未延迟初始化的单例bean的依赖项时,ApplicationContext在启动时创建延迟初始化的bean,因为它必须满足单例的依赖项。延迟初始化的bean被注入到一个没有延迟初始化的单例bean中。

也可以放在beans中 这样所有的bean默认懒加载

<beans default-lazy-init="true">
        <!-- no beans will be pre-instantiated... -->
</beans>
Autowiried
  • 自动装配可以大大减少指定属性或构造函数参数的需要。(本章其他地方讨论的其他机制,如bean模板,在这方面也很有价值。)
  • 随着对象的发展,自动装配可以更新配置。 例如,如果您需要向类中添加依赖项,则无需修改配置即可自动满足该依赖项。
ModeExplanation
no(默认)无自动装配。 Bean引用必须通过ref元素定义。 对于较大的部署,建议不要更改默认设置,因为明确指定协作者可以提供更好的控制和清晰度。 在某种程度上,它记录了系统的结构。
byName按属性名称Autowiried。 Spring寻找与需要自动装配的属性同名的bean。 例如,如果一个bean定义被设置为按名称自动装配,并且包含一个master属性(即,它具有setMaster(…)方法),Spring将查找一个名为master的bean定义,并使用它来设置 属性。
byType如果容器中恰好存在一个属性类型的bean,则允许自动装配该属性。如果存在多个异常,则抛出一个致命异常,这表明您不能为该bean使用byType自动装配。如果没有匹配的bean,则什么也不会发生;属性未设置。
constructor类似于byType,但适用于构造函数参数。如果容器中没有一个构造函数参数类型的bean,则会引发致命错误。

您可以将自动装配行为与依赖项检查相结合,依赖项检查在自动装配完成后执行。

当自动装配在整个工程中一致的使用时其效果最好。如果通常情况下不使用自动装配,仅在一两个bean定义中使用自动装配开发人员可能感到非常困惑。

限制和缺陷

  • propertyconstructor-arg设置中的显式式依赖项始终覆盖自动装配。您无法自动装配简单的属性,例如图元,StringsClasses(以及此类简单属性的数组)。 这种限制是由设计造成的。

  • 自动装配不如显式连接精确。尽管如上表所述,Spring谨慎地避免猜测,以免产生可能导致意外结果的歧义,但Spring管理对象之间的关系不再明确地记录下来。

  • Spring容器中能产生文档的工具可能得不到配置信息。

  • setter方法或构造函数参数指定的类型进行自动装配时可能匹配到容器中多个bean的定义。对于数组,集合或Maps而言,这是一个不必要的问题。然而对于只期望一个值的依赖而言,这个歧义性不能任意解决。如果不能获得唯一的bean定义,会抛出异常。

在后一种情况中,您有几个选项 :

  • 放弃自动布线,转而使用明确的布线。
  • 通过将其bean的autowire-candidate属性设置为false,避免自动装配bean定义,如下一节所述。
  • 通过将其元素的primary属性设置为true,将其中一个bean定义指定为主要候选对象。
  • 如基于注释的容器配置中所述,通过基于注释的配置实现更细粒度的控件。 如3.9小节 “基于注解的容器配置”。

在单个bean的基础上,你可以排除bean在自动装配之外。在Spring的XML形式中,设置元素的autowire-candidate特性为false;容器会使自动装配基础框架不能得到指定bean定义(包括注解类型的配置,例如@Autowired)。

你也可以根据bean名称的匹配模式限制自动装配的候选目标。顶层的元素可以接收default-autowire-candidates特性中的一个或多个模式。例如,为了限制自动装配候选目标匹配任何名字以Repository结尾的bean,可以提供一个*Repository值。为了提供多种模式,可以定义一个以逗号为分隔符的列表。bean定义中autowire-candidate特性显示的值true或false最是优先起作用的,对于这些bean而言,模式匹配规则不起作用。

这些技术对于那些你从不想通过自动装配方式注入到其它bean中的beans而言是很有用的。这不意味着一个排除的bean它本身不能通过自动装配进行配置。更确切的说,bean本身不是一个进行其它bean进行自动装配的候选者。

在大多数应用场景中,容器中的大多数bean是单例的。当一个单例bean需要与另一个单例bean协作时,或一个非单例bean需要与另一个非单例bean协作时,你通常通过定义一个bean作为另一个bean的一个属性来处理这个依赖关系。当bean的生命周期不同时问题就出现了。假设一个单例bean A需要使用非单例(标准)bean B时,也许A中的每一个方法调用都要使用bean B。容器仅创建单例bean A一次,因此仅有一次设置属性的机会。容器不能在每次需要bean B时提供一个bean B的新的实例。

* 查找方法注入 (解决单例对象注入多例对象问题)

Spring的方法注入依赖于CGLIB,需要添加Jar包com.springsource.cn.sf.cglib-2.2.0.jar

查找方法注入是容器的一种覆盖其管理的beans中的方法的能力,可以返回容器中另一个命名bean查找结果。查找通常会涉及到一个标准bean,如前一小节中讲的那样。Spring框架实现了查找方法注入,它是通过使用CGLIB库生成的字节码来动态的产生一个覆盖这个方法的子类。

  • 为了使此动态子类起作用, Spring bean容器要进行子类化的类不能是final ,要覆盖的方法也不能为final
  • 对具有abstract方法的类进行单元测试需要您自己对该类进行子类化,并提供该abstract方法的存根实现。
  • 组件扫描也需要具体的方法,这需要具体的类别。
  • 一个更关键的限制是查找方法不能与工厂方法一起工作,尤其是在配置类中不能与@Bean方法同时起作用,由于那种情况下容器不能控制实例的创建,因此不能在飞速写入中创建一个运行时产生的子类。
  • 最后,方法注入的目标对象不能被序列化。

查看CommandManager前面的代码片段中的类,您会看到Spring容器将动态覆盖该createCommand() 方法的实现。您的CommandManager类将没有任何Spring依赖项:

package fiona.apple;

// no more Spring imports!

public abstract class CommandManager {

        public Object process(Object commandState) {
                // grab a new instance of the appropriate Command interface
                Command command = createCommand();
                // set the state on the (hopefully brand new) Command instance
                command.setState(commandState);
                return command.execute();
        }

        // okay... but where is the implementation of this method?
        protected abstract Command createCommand();
}

在包含要注入的方法的客户端类(CommandManager在本例中为)中,要注入的方法需要以下形式的签名:

<public|protected> [abstract] <return-type> theMethodName(no-arguments);

如果方法为abstract,则动态生成的子类将实现该方法。否则,动态生成的子类将覆盖原始类中定义的具体方法。例如:

<!-- a stateful bean deployed as a prototype (non-singleton) -->
<bean id="myCommand" class="fiona.apple.AsyncCommand" scope="prototype">
        <!-- inject dependencies here as required -->
</bean>

<!-- commandProcessor uses statefulCommandHelper -->
<bean id="commandManager" class="fiona.apple.CommandManager">
        <lookup-method name="createCommand" bean="myCommand"/>
</bean>

每当需要myCommand bean 的新实例时,标识为commandManager的bean 就会调用其自己的方法。如果确实需要,您必须小心地将bean 部署为原型 (prototype)

或者,在基于注释的组件模型中,您可以通过@Lookup注释声明一个查找方法:

public abstract class CommandManager {

        public Object process(Object commandState) {
                MyCommand command = createCommand();
                command.setState(commandState);
                return command.execute();
        }
		//第一种写法
        @Lookup
        protected abstract MyCommand createCommand();
   		 //第二种写法
     	@Lookup("myCommand")
        protected abstract Command createCommand();
}

注意,您通常会用一个具体的存根实现来声明这样的带注释的查找方法,以便使它们与Spring组件扫描规则兼容,其中抽象类在缺省情况下会被忽略。此限制不适用于显式注册或显式导入的bean类。

任意方法替换(解决单例对象注入多例对象问题)

一种比查找方法注入更少使用的形式是用另一种方法实现替换管理的bean中任意方法的能力。用户可以安全跳过本节剩下的部分,直到这个方法真正需要的时候再看。

在基于XML的配置元数据中,对于一个部署的bean,你可以通过replaced-method元素用另一个方法实现替换现有的方法实现。考虑下面的类,有一个我们想覆盖的computeValue方法:

public class MyValueCalculator {
 
    public String computeValue(String input) {
        // some real code...
    }
 
    // some other methods...
 
}

实现了org.springframework.beans.factory.support.MethodReplacer接口的类提供了一种新的方法定义。

public class ReplacementComputeValue implements MethodReplacer {
 
    public Object reimplement(Object o, Method m, Object[] args) throws Throwable {
        // get the input value, work with it, and return a computed result
        String input = (String) args[0];
        ...
        return ...;
    }
}

部署最初的类的bean定义和指定的重写方法如下:

<bean class="x.y.z.MyValueCalculator" id="myValueCalculator">
    <!-- arbitrary method replacement -->
    <replaced-method name="computeValue" replacer="replacementComputeValue">
        String</arg-type>
    </replaced-method>
</bean>
 
<bean class="a.b.c.ReplacementComputeValue" id="replacementComputeValue"></bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值