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对象好像也能实现相同的功能,除非这个父类是不可继承的

posted @ 2020-01-08 09:55  葬月!  阅读(554)  评论(0编辑  收藏  举报