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