import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.stereotype.Service;
@Service("injectSimple")
public class InjectSimple {
@Value("John Mayer")
private String name;
@Value("39")
private int age;
@Value("1.92")
private float height;
@Value("false")
private boolean programmer;
@Value("1241401112")
private Long ageInSeconds;
public static void main(String... args) {
GenericXmlApplicationContext ctx =
new GenericXmlApplicationContext();
ctx.load("classpath:spring/app-context-annotation.xml");
ctx.refresh();
InjectSimple simple = (InjectSimple) ctx.getBean("injectSimple");
System.out.println(simple);
ctx.close();
}
public String toString() {
return "Name: " + name + "\n"
+ "Age: " + age + "\n"
+ "Age in Seconds: " + ageInSeconds + "\n"
+ "Height: " + height + "\n"
+ "Is Programmer?: " + programmer;
}
}
配置参数
import org.springframework.stereotype.Component;
@Component("injectSimpleConfig")
public class InjectSimpleConfig {
private String name = "John Mayer";
private int age = 39;
private float height = 1.92f;
private boolean programmer = false;
private Long ageInSeconds = 1_241_401_112L;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public float getHeight() {
return height;
}
public boolean isProgrammer() {
return programmer;
}
public Long getAgeInSeconds() {
return ageInSeconds;
}
}
<bean id="injectSimpleConfig"
class="com.apress.prospring5.ch3.xml.InjectSimpleConfig"/>
<bean id="injectSimpleSpel"
class="com.apress.prospring5.ch3.xml.InjectSimpleSpel"
p:name="#{injectSimpleConfig.name}"
p:age="#{injectSimpleConfig.age + 1}"
p:height="#{injectSimpleConfig.height}"
p:programmer="#{injectSimpleConfig.programmer}"
p:ageInSeconds="#{injectSimpleConfig.ageInSeconds}"/>
使用SPEL
import org.springframework.context.support.GenericXmlApplicationContext;
public class HierarchicalAppContextUsage {
public static void main(String... args) {
GenericXmlApplicationContext parent = new GenericXmlApplicationContext();
parent.load("classpath:spring/parent-context.xml");
parent.refresh();
GenericXmlApplicationContext child = new GenericXmlApplicationContext();
child.load("classpath:spring/child-context.xml");
child.setParent(parent);
child.refresh();
Song song1 = (Song) child.getBean("song1");
Song song2 = (Song) child.getBean("song2");
Song song3 = (Song) child.getBean("song3");
System.out.println("from parent ctx: " + song1.getTitle());
System.out.println("from child ctx: " + song2.getTitle());
System.out.println("from parent ctx: " + song3.getTitle());
child.close();
parent.close();
}
}
子和父的上下文
<?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:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<context:component-scan
base-package="com.apress.prospring5.ch3.annotated"/>
<util:map id="map" map-class="java.util.HashMap">
<entry key="someValue" value="It's a Friday, we finally made it"/>
<entry key="someBean" value-ref="lyricHolder"/>
</util:map>
<util:properties id="props">
<prop key="firstName">John</prop>
<prop key="secondName">Mayer</prop>
</util:properties>
<util:set id="set" set-class="java.util.HashSet">
<value>I can't believe I get to see your face</value>
<ref bean="lyricHolder"/>
</util:set>
<util:list id="list" list-class="java.util.ArrayList">
<value>You've been working and I've been waiting</value>
<ref bean="lyricHolder"/>
</util:list>
</beans>
@Service("injectCollection")
public class CollectionInjection {
@Resource(name="map")
private Map<String, Object> map;
@Resource(name="props")
private Properties props;
@Resource(name="set")
private Set set;
@Resource(name="list")
private List list;
public static void main(String... args) {
GenericXmlApplicationContext ctx =
new GenericXmlApplicationContext();
ctx.load("classpath:spring/app-context-annotation.xml");
ctx.refresh();
CollectionInjection instance = (CollectionInjection)
ctx.getBean("injectCollection");
instance.displayInfo();
ctx.close();
}
...
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@Service("injectCollection")
public class CollectionInjection {
@Autowired
@Qualifier("map")
private Map<String, Object> map;
...
}
注入Collections
public class Singer {
private String lyric = "I played a quick game of chess with the salt
and pepper shaker";
public void sing() {
//commented because it pollutes the output
//System.out.println(lyric);
}
}
public interface DemoBean {
Singer getMySinger();
void doSomething();
}
public class StandardLookupDemoBean
implements DemoBean {
private Singer mySinger;
public void setMySinger(Singer mySinger) {
this.mySinger = mySinger;
}
@Override
public Singer getMySinger() {
return this.mySinger;
}
@Override
public void doSomething() {
mySinger.sing();
}
}
public abstract class AbstractLookupDemoBean
implements DemoBean {
public abstract Singer getMySinger();
@Override
public void doSomething() {
getMySinger().sing();
}
}
<beans>
<bean id="singer" class="com.apress.prospring5.ch3.Singer"
scope="prototype"/>
<bean id="abstractLookupBean"
class="com.apress.prospring5.ch3.AbstractLookupDemoBean">
<lookup-method name="getMySinger" bean="singer"/>
</bean>
<bean id="standardLookupBean"
class="com.apress.prospring5.ch3.StandardLookupDemoBean">
<property name="mySinger" ref="singer"/>
</bean>
</beans>
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.util.StopWatch;
public class LookupDemo {
public static void main(String... args) {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("classpath:spring/app-context-xml.xml");
ctx.refresh();
DemoBean abstractBean = ctx.getBean("abstractLookupBean",
DemoBean.class);
DemoBean standardBean = ctx.getBean("standardLookupBean",
DemoBean.class);
displayInfo("abstractLookupBean", abstractBean);
displayInfo("standardLookupBean", standardBean);
ctx.close();
}
public static void displayInfo(String beanName, DemoBean bean) {
Singer singer1 = bean.getMySinger();
Singer singer2 = bean.getMySinger();
System.out.println("" + beanName + ": Singer Instances the Same? "
+ (singer1 == singer2));
StopWatch stopWatch = new StopWatch();
stopWatch.start("lookupDemo");
for (int x = 0; x < 100000; x++) {
Singer singer = bean.getMySinger();
singer.sing();
}
stopWatch.stop();
System.out.println("100000 gets took "
+ stopWatch.getTotalTimeMillis() + " ms");
}
}
方法注入,以及单元测试
@Component("singer)
@Scope("prototype")
public class Singer {
private String lyric = "I played a quick game of chess
with the salt and pepper shaker";
public void sing() {
// commented to avoid console pollution
//System.out.println(lyric);
}
}
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.stereotype.Component;
@Component("abstractLookupBean")
public class AbstractLookupDemoBean implements DemoBean {
@Lookup("singer")
public Singer getMySinger() {
return null; // overriden dynamically
}
@Override
public void doSomething() {
getMySinger().sing();
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component("standardLookupBean")
public class StandardLookupDemoBean implements DemoBean {
private Singer mySinger;
@Autowired
@Qualifier("singer")
public void setMySinger(Singer mySinger) {
this.mySinger = mySinger;
}
@Override
public Singer getMySinger() {
return this.mySinger;
}
@Override
public void doSomething() {
mySinger.sing();
}
}
方法注入
public class ReplacementTarget {
public String formatMessage(String msg) {
return "<h1>" + msg + "</h1>";
}
public String formatMessage(Object msg) {
return "<h1>" + msg + "</h1>";
}
}
import org.springframework.beans.factory.support.MethodReplacer;
import java.lang.reflect.Method;
public class FormatMessageReplacer
implements MethodReplacer {
@Override
public Object reimplement(Object arg0, Method method, Object... args)
throws Throwable {
if (isFormatMessageMethod(method)) {
String msg = (String) args0;
return "<h2>" + msg + "</h2>";
} else {
throw new IllegalArgumentException("Unable to reimplement method "
+ method.getName());
}
}
private boolean isFormatMessageMethod(Method method) {
if (method.getParameterTypes().length != 1) {
return false;
}
if (!("formatMessage".equals(method.getName()))) {
return false;
}
if (method.getReturnType() != String.class) {
return false;
}
if (method.getParameterTypes()[0] != String.class) {
return false;
}
return true;
}
}
<beans>
<bean id="methodReplacer"
class="com.apress.prospring5.ch3.FormatMessageReplacer"/>
<bean id="replacementTarget"
class="com.apress.prospring5.ch3.ReplacementTarget">
<replaced-method name="formatMessage" replacer="methodReplacer">
<arg-type>String</arg-type>
</replaced-method>
</bean>
<bean id="standardTarget"
class="com.apress.prospring5.ch3.ReplacementTarget"/>
</beans>
方法替代
本文深入探讨了Spring框架中依赖注入的各种方式,包括属性注解注入、构造器注入、方法注入及方法替代等,展示了如何在Java应用中利用Spring进行高效、灵活的依赖管理。
2747

被折叠的 条评论
为什么被折叠?



