spring 方法注入、方法替换

spring 提供了很多的注入方式,set注入、构造注入、p命名空间、c命名空间、字段注入等等,这些没啥可说的了。

方法注入

因为开发时我需要spring管理一个实例,但是这个实例并非单例,应该每一次调用都是一个新的实例。所以这时候有需要方法注入。

先创建一个Test类

package com.lhf.lookup;

public class Test {

    public void work(){
        System.out.println("我是一名java开发工程师");
    }
}

然后创建Dome,从代码中可以看出,Dome类依赖于Test

package com.lhf.lookup;

public class Dome {

    private Test test;

    public Test getTest() {
        return test;
    }

    public void setTest(Test test) {
        this.test = test;
    }

    public void say(){
        System.out.println("我爱我的祖国");
    }
}

现在配置 xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <!--bean的默认作用域是singleton,现在需要把它声明为prototype-->   <bean id="test" class="com.lhf.lookup.Test" scope="prototype"> </bean>   <bean id="dome" class="com.lhf.lookup.Dome">
    <!--通过lookup-method-->  
        <lookup-method name="getTest" bean="test"/>
    </bean>

</beans>

这样Dome每次调用Test实例时,都会是一个新的。

package com.lhf.lookup;

import org.springframework.context.support.GenericXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        GenericXmlApplicationContext context = new GenericXmlApplicationContext();
        context.load("classpath:spring/lookup.xml");
        context.refresh();
        Dome dome = (Dome)context.getBean("dome");
        System.out.println(dome.getTest() == dome.getTest());
        context.close();
    }
}

基于注解方式:

package com.lhf.lookup;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("test")
@Scope("prototype")
public class Test {

    public void work(){
        System.out.println("我是一名java开发工程师");
    }
}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

package com.lhf.lookup;

import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class Dome {

    @Resource
    private Test test;

    @Lookup
    public Test getTest() {
        return test;
    }

    public void setTest(Test test) {
        this.test = test;
    }

    public void say(){
        System.out.println("我爱我的祖国");
    }
}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
package com.lhf.lookup;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.lhf.lookup")
public class Config {
}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
package com.lhf.lookup;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        Dome bean = context.getBean(Dome.class);
        System.out.println(bean.getTest() == bean.getTest());
        context.close();
    }
}

方法替换

这个注入方式感觉有点鸡肋了,我继承父类重写方法也能实现同样的功能,好像还简单粗暴好理解嘞。可以把它看成是aop

先创建一个有3个重载的方法

package com.lhf.replacement;

public class TestServiceImpl {

    public void say() {
        System.out.println("我说你是猪1");
    }

    public void say(String mes) {
        System.out.println("我说你是猪2");
    }

    public void say(Object mes) {
        System.out.println("我说你是猪3");
    }
}

然后创建一个继承 MethodReplacer 的类,这里重写的方法是要替换的结果方法 譬如: 把TestServiceImpl中的第一个无参方法替换成下边的实现

package com.lhf.replacement;

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

import java.lang.reflect.Method;

public class Replace implements MethodReplacer {

    @Override
    public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
        System.out.println("替换原来的方法");
        return null;
    }
}

配置xml文件 replaced-method 声明替换方法,name 是要替换的方法名,replacer 要替换的bean对象,<arg-type/> 是处理重载的

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="replace" class="com.lhf.replacement.Replace"/>

    <bean id="testService" class="com.lhf.replacement.TestServiceImpl">
        <replaced-method name="say" replacer="replace">
            <arg-type/>
        </replaced-method>
        <replaced-method name="say" replacer="replace">
            <arg-type match="java.lang.String"/>
        </replaced-method>
        <replaced-method name="say" replacer="replace">
            <arg-type match="java.lang.Object"/>
        </replaced-method>
    </bean>
</beans>

测试:

package com.lhf.replacement;

import org.springframework.context.support.GenericXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        GenericXmlApplicationContext context = new GenericXmlApplicationContext();
        context.load("spring/replacement.xml");
        context.refresh();
        TestServiceImpl service = (TestServiceImpl)context.getBean("testService");
        System.out.println(">>>>>>>>>>>>>>>>>>>>>");
        service.say();
        System.out.println(">>>>>>>>>>>>>>>>>>>>>");
        service.say("章鱼是猪");
        System.out.println(">>>>>>>>>>>>>>>>>>>>>");
        service.say("张宇是猪");
        context.close();
    }
}

他这个方法重载貌似并不太好,我个人觉得,我继承父类,重写父类方法声明成bean对象好像也能实现相同的功能,除非这个父类是不可继承的。

原文地址:https://www.cnblogs.com/Tiandaochouqin1/p/12165029.html

时间: 2024-08-06 04:05:12

spring 方法注入、方法替换的相关文章

spring依赖注入方法及原理

依赖注入就是在程序运行时期,由外部容器动态的将依赖对象注入到组件中,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做. spring有多种依赖注入的形式,下面仅介绍spring通过xml进行IOC配置的方式: 1.set注入 这是最简单的注入方式,假设有一个PersonServiceBean,类中需要实例化一个PersonDao对象,那么就可以定义一个private的PersonDao成员变量,然后创建

Spring 4.2 方法注入解决单例Bean的原型Bean依赖问题

当你在单例Bean中使用原型Bean依赖时,注意,依赖在实例化时解析.因此,如果你依赖注入一个原型Bean到单例Bean中,新的原型Bean被实例化然后依赖注入到单例Bean中.提供给单例Bean的原型实例是唯一的. 然而,假设你想单例Bean在运行时多次获取一个新的原型Bean的实例.你不能依赖注入一个原型Bean到你的单例Bean中,因为注入只发生一次,当Spring容器实例化单例Bean时解析并注入它的依赖.如果你在运行时多次需要一个新的原型Bean,可以使用方法注入. 在大多数应用程序情

Spring应用教程-2 方法注入

我们通常使用lookup方法注入,它可使Spring替换一个Bean的抽象或具体方法,返回查找容器中,其他Bean的结果,被查找的Bean通常是一个non-singleton Bean. 无状态的Bean的作用域一般可以配置成singleton单实例,如果我们向singleton的BeanA注入prototype的BeanB,并希望每次调用BeanA的getBeanB()时都能返回一个新的BeanB,使用传统的注入方式方法将无法实现这样的要求.因为singleton的Bean注入关联Bean的动

【Spring】IOC之方法注入

方法注入在我看来就是为了实现在单例类中取得不同的实例类对象. 当一个Bean依赖的Bean和自己生命周期不同的时候:如Bean A依赖Bean B,Bean A 是singleton,如果需要在Bean A每次用到Bean B的时候都用一个Bean B的新的实例(注意是新的),即使通过在配置文件设置Bean B的 property或者 contructor-arg是不能实现的.这时候只能在Bean A中用Bean B的时候动态得到. 或者可以这么说, 调用一个singleton类型bean A的

spring 构造方法注入和setter方法注入的XML表达

1.构造方法注入 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > 3 <beans> 4 <bean id="person&quo

Spring中使用Map、Set、List、数组、属性集合的注入方法配置文件

(1)下边的一个java类包含了所有Map.Set.List.数组.属性集合等这些容器,主要用于演示Spring的注入配置: package com.lc.collection; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; public class Department { private String name; private String []

Spring 自动装配;方法注入

通过配置defalut-autowire属性,Spring IOC容器可以自动为程序注入Bean:默认是no(不启用自动装配). default-autowire的类型有: byName:通过名称自动进行匹配 byType:通过属性自动进行匹配 示例如下: 一个实体类people public class People{ private int id; private String name; private int age; private Dog dog; } beans.xml配置: <?

【Spring】JavaBean的2种注入方法深入浅出

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 在定义了 JavaBean 装载信息之后需要对其赋值.一个 JavaBean 的赋值可以通过构造方法完成初始化,或者通过 set()方法初始化和改变属性值.下面分别介绍如何在 XML 中配置 JavaBean 的属性为构造方法和 set()方法传递参数. 一.构造注入 在类被实例化的时候,它的构造方法被调用并且只能调用一次.所以它被用于类的初始化操作.<constructor-arg>是&

spring依赖注入之构造函数注入,set方法注入

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org