所以我使用Spring注释@Autowire和@Qualifier进行依赖注入练习某些代码。代码完美地处理了输出中的一点异常。
Coach.java
package com.luv2code.springdemo;
public interface Coach {
public String getDailyWorkout();
public String getDailyFortune();
}
SwimCoach.java
package com.luv2code.springdemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class SwimCoach implements Coach {
@Autowired
@Qualifier("randomFortuneService")
private FortuneService fortuneService;
@Value("${foo.email}")
private String email;
@Value("${foo.team}")
private String team;
public SwimCoach() {
System.out.println("Inside Swimcoach no-arg constructor");
}
@Override
public String getDailyWorkout() {
return "Swim 1000 meters as a warm up.";
}
@Override
public String getDailyFortune() {
return fortuneService.getFortune();
}
public String getEmail() {
return email;
}
public String getTeam() {
return team;
}
}
FortuneService.java
package com.luv2code.springdemo;
public interface FortuneService {
public String getFortune();
}
RandomFortuneService.java
package com.luv2code.springdemo;
import java.util.Random;
import org.springframework.stereotype.Component;
//with @Component, the class is ready to be scanned by Spring.
@Component
public class RandomFortuneService implements FortuneService {
// create an array of strings
private String[] data = {
"perseverance is the key to success.",
"Diligence is the mother of good luck.",
"Your Journey towards the success is itself a reward."
};
private Random myRandom = new Random();
@Override
public String getFortune() {
int index = myRandom.nextInt(data.length);
String theFortune = data[index];
return theFortune;
}
}
PracticeHelloSpringApp.java
package com.luv2code.springdemo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class PracticeHelloSpringApp {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
SwimCoach coach = context.getBean("swimCoach",SwimCoach.class);
//In the above code,SwimCoach defines two extra methods getEmail and getTeam which are not a part of Coach interface.
//So we need to create coach variable of type SwimCoach class with which we can access interface methods as well as class methods.
System.out.println(coach.getDailyWorkout());
System.out.println(coach.getDailyFortune());
System.out.println(coach.getEmail());
System.out.println(coach.getTeam());
context.close();
}
}
的applicationContext.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"
xmlns:context="http://www.springframework.org/schema/context"
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">
<context:component-scan base-package="com.luv2code.springdemo"/>
<context:property-placeholder location="classpath:sport.properties"/>
在SwimCoach.java中,我正在使用属性文件来注入值。还有另外三个fortuneService实现返回一些字符串。为了确保使用RandomFortuneService,我正在使用@Qualifier。现在输出有点奇怪。
May 12, 2018 10:31:04 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1a93a7ca: startup date [Sat May 12 10:31:04 IST 2018]; root of context hierarchy
May 12, 2018 10:31:05 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
inside constructor of PingPongCoach
Inside Swimcoach no-arg constructor
Swim 1000 meters as a warm up.
perseverance is the key to success.
myeasycoach@luv2code.com
Silly Java Coders
May 12, 2018 10:31:06 AM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@1a93a7ca: startup date [Sat May 12 10:31:04 IST 2018]; root of context hierarchy
如果你注意到,那里有 PingPongCoach的内部构造函数,它完全是Coach接口的不同实现。在这里我也使用 @Qualifier(“randomFortuneService”)作为构造函数注入。
PingPongCoach.java
package com.luv2code.springdemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
//Incase of default bean ID, It would be "pingPongCoach".
@Component("myPingPongCoach")
public class PingPongCoach implements Coach {
private FortuneService fortuneService;
//This is the case when we have multiple implementations of FortuneService and we are constructor injection for
//injecting dependency with the use of @Autowired and @Qualifier. Check the @Qualifier annotation inside of the constructor arguments.
@Autowired
public PingPongCoach(@Qualifier("randomFortuneService") FortuneService fortuneService) {
super();
System.out.println("inside constructor of PingPongCoach");
this.fortuneService = fortuneService;
}
@Override
public String getDailyWorkout() {
return "Ping Pong is no sport...You don't need any practice!!";
}
@Override
public String getDailyFortune() {
return fortuneService.getFortune();
}
}
有谁能告诉我为什么在这里调用PingPongCoach No-arg构造函数?
答案 0 :(得分:0)
你用@Component
@Component("myPingPongCoach")
public class PingPongCoach implements Coach
因此,在组件扫描期间,spring创建并初始化它。
您为构造函数提供了一个参数来抑制默认构造函数,因此Spring会选择它。