假设我有这样的接口:
interface Country {}
class USA implements Country {}
class UK implements Country ()
Run Code Online (Sandbox Code Playgroud)
这个配置xml片段:
<bean class="USA"/>
<bean id="country" class="UK"/>
<bean id="main" class="Main"/>
Run Code Online (Sandbox Code Playgroud)
如何控制下面自动连接的依赖项?我想要英国人.
class Main {
private Country country;
@Autowired
public void setCountry(Country country) {
this.country = country;
}
}
Run Code Online (Sandbox Code Playgroud)
我使用的是Spring 3.0.3.RELEASE.
有没有人试图根据条件将不同的bean自动连接到Spring管理的bean?例如,如果满足某些条件,则注入A类,否则B?我在其中一个Google搜索结果中看到,使用SpEL(Spring Expression Language)可以实现,但无法找到一个有效的示例.
有谁知道我是否应该使用属性占位符作为限定符中的表达式?我似乎无法让这个工作.
我使用的是Spring 3.0.4.
@Controller
public class MyController {
@Autowired
@Qualifier("${service.class}")
Service service;
}
@Service
@Qualifier("ServiceA")
ServiceA implements Service {
public void print() {
System.out.println("printing ServiceA.print()");
}
}
@Service
@Qualifier("ServiceB")
ServiceB implements Service {
public void print() {
System.out.println("printing ServiceB.print()");
}
}
Run Code Online (Sandbox Code Playgroud)
XML:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:/etc/config.properties"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
config.properties:
config.properties
service.class=serviceB
Run Code Online (Sandbox Code Playgroud) 我正在使用Spring Boot for Java独立应用程序.我有一个使用服务的bean.我想在运行时注入该服务的不同实现,基于Spring的属性文件中的属性(就此而言为4).
这听起来像工厂模式,但Spring也允许使用注释来解决问题,就像这样.
@Autowired @Qualifier("selectorProperty") private MyService myService;
Run Code Online (Sandbox Code Playgroud)
然后在beans.xml文件中我有一个别名,这样我就可以在@Qualifier中使用该属性.
<alias name="${selector.property}" alias="selectorProperty" />
Run Code Online (Sandbox Code Playgroud)
在我的不同实现中,我会有不同的限定符.
@Component("Selector1")
public class MyServiceImpl1
@Component("Selector2")
public class MyServiceImpl2
Run Code Online (Sandbox Code Playgroud)
application.properties
selector.property = Selector1
selector.property = Selector2
Run Code Online (Sandbox Code Playgroud)
而对于工厂模式,在Spring中,您可以使用ServiceLocatorFactoryBean来创建一个可以提供相同功能的工厂.
<bean
class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean"
id="myServiceFactory">
<property
name="serviceLocatorInterface"
value="my.company.MyServiceFactory">
</property>
</bean>
public interface MyServiceFactory
{
MyService getMyService(String selector);
}
Run Code Online (Sandbox Code Playgroud)
然后在您的bean中,您可以使用类似的东西在运行时获得正确的实现,具体取决于属性的值.
@Value("${selector.property}") private String selectorProperty;
@Autowired private MyServiceFactory myServiceFactory;
private MyService myService;
@PostConstruct
public void postConstruct()
{
this.myService = myServiceFactory.getMyService(selectorProperty);
}
Run Code Online (Sandbox Code Playgroud)
但是这个解决方案的问题是我找不到一种方法来避免使用XML来定义工厂,我想只使用注释.
所以问题是,是否有一种方法可以仅使用注释来使用ServiceLocatorFactoryBean(或类似的东西),或者如果我不想在XML中定义bean,我是否被迫使用@Autowired @Qualifier方法?或者是否还有其他方法可以在运行时根据Spring 4避免使用XML的属性注入不同的服务?如果您的答案只是使用@Autowired @Qualifier别名,请说明为什么这比使用众所周知的工厂模式更好.
使用额外的XML迫使我@ImportResource("classpath:beans.xml")在我的Launcher类中使用,我也不愿意使用它.
谢谢.
我正在开发一个Spring 3.1 MVC应用程序,对于我的一个场景,我不得不编写两个DAO实现.我想知道如何基于另一个对象的属性在服务层中自动装配它.
例如,
class Vehicle {
private name;
private type;
..
..
..
}
@Service
class VehicleServiceImpl implements VehicleService {
// There are two implementations to this DAO
// if Vehicle.type == "CAR", inject CarDAO
// if Vehicle.type == "TRAIN", inject TrainDAO
@Autowired
private VehicleDAO vehicleDAO ;
}
@Repository
class CarDAO implements VehicleDAO {
}
@Repository
class TrainDAO implements VehicleDAO {
}
Run Code Online (Sandbox Code Playgroud)
如果我的车辆是汽车,我需要自动装载CarDAO,如果是火车,我需要自动装载TrainDAO
在3.1版本中实现这一点的最佳方法是什么?
我希望使用上下文属性占位符或@Qualifier注释,但这些都是基于某些属性限制查找.我不知道如何在运行时基于另一个对象的属性执行此操作.
鉴于此代码:
public interface Service {}
@Component
@Qualifier("NotWanted")
public class NotWantedService implements Service {}
@Component
@Qualifier("Wanted")
public class WantedService implements Service {}
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(NotWantedService.class);
ctx.register(WantedService.class);
ctx.refresh()
Run Code Online (Sandbox Code Playgroud)
我现在该怎么做:
ctx.getBean(Service.class)
Run Code Online (Sandbox Code Playgroud)
在一种方式,只会得到一个@Qualifier("Wanted")而不是一个@Qualifier("NotWanted")?我特别询问是否有可能使用它getBean,而不是注入一个类,然后使用那个作为一种代理.
我有一个Java EE + Spring应用程序,它支持XML配置的注释.bean总是有原型范围.
我现在的应用程序业务规则取决于用户请求所在的国家/地区.所以我会有这样的事情(请记住这个例子大大简化了):
@Component
public class TransactionService {
@Autowired
private TransactionRules rules;
//..
}
@Component
@Qualifier("US")
public class TransactionRulesForUS implements TransactionRules {
//..
}
@Component
@Qualifier("CANADA")
public class TransactionRulesForCanada implements TransactionRules {
//..
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种方法,使自动布线机制根据当前请求的国家/地区自动注入正确的bean(在此示例中为美国或加拿大).该国家/地区将存储在ThreadLocal变量中,并且会在每个请求中更改.对于没有自己特定规则的所有国家,也会有全球一流的课程.
我想我必须自定义Spring决定如何创建它将注入的对象的方式.我发现这样做的唯一方法是使用FactoryBean,但这并不是我所希望的(不够通用).我希望做这样的事情:
我在正确的道路上吗?对我有什么想法吗?
谢谢.
我试图使用属性占位符作为@Qualifier的属性,如下所示:
@Autowired
@Qualifier("${beanName}")
private MyBean myBean;
Run Code Online (Sandbox Code Playgroud)
但是,即使属性占位符作为String值可用,这也不起作用:
@Value("${beanName}")
private String beanName;
Run Code Online (Sandbox Code Playgroud)
这里有什么好的解决方法,非常感谢.
我对Sprint很新,我使用Spring 3.x和roo1.1.1作为我的应用程序.
我有一个接口的多个实现,它将@Autowired到其他不同的类中.我只能决定在运行时使用哪个实现.这应该像工厂模式一样实现.
public interface SomeInterface {
public void doSomething();
}
Run Code Online (Sandbox Code Playgroud)
实施1.
public class SomeOb implements SomeInterface {
public void doSomething() {
//Do something for first implementation here
}
}
Run Code Online (Sandbox Code Playgroud)
实施2.
public class SomeOtherOb implements SomeInterface {
public void doSomething() {
//Do something for first implementation here
}
}
Run Code Online (Sandbox Code Playgroud)
现在在我的服务中,我需要这样的Autowired
@Service
public class MyService {
@Autowired
SomeInterface ob;
//Rest of the code here
}
Run Code Online (Sandbox Code Playgroud)
1)选择哪个实现为Autowired的逻辑只知道运行时,所以我不能使用@Qualifier注释来限定它.2)我尝试创建一个像FactoryBean
public class SomeFactoryBean implements FactoryBean<SomeInterface> {
@Override
public SomeInterface getObject() throws Exception {
if(/*Somecondition*/) { …Run Code Online (Sandbox Code Playgroud)