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

  • 相关阅读:
    Python网络爬虫第三弹《爬取get请求的页面数据》
    18.增量式爬虫
    17.基于scrapy-redis两种形式的分布式爬虫
    关于进程内存磁盘的一些命令
    linux其他命令
    ls -用于显示指定工作目录下之内容(列出目前工作目录所含之文件及子目录)
    mkdir和touch
    ls -列出当前目录下所有的文件或者目录
    cat -用于连接文件并打印到标准输出设备上
    rm -移动文件
  • 原文地址:https://www.cnblogs.com/Tiandaochouqin1/p/12165029.html
Copyright © 2011-2022 走看看