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

  • 相关阅读:
    对象形式传递
    解决DLNA方案的技术框架
    关于DLNA
    MAC配置Xcode的Cocos2d-x环境
    什么叫做双缓冲?
    Window7 Cocos2d-x配置开发环境
    Windows 8.1 Update 2更新了什么?
    微软发布Windows Phone 8.1 Update 和中文版Cortana“小娜”
    大开眼界 游览Facebook香港办公室
    小米的“假照片”危机
  • 原文地址:https://www.cnblogs.com/Tiandaochouqin1/p/12165029.html
Copyright © 2011-2022 走看看