如何为外部非spring项目中的类设置自动布线




我有一个需求,我在Spring项目中定义了一个契约,并希望在部署期间自动连接一个外部JAR,以实现契约(一组接口)。我不想强制外部JAR依赖于Spring,以便它尽可能灵活。在我的Spring项目中,无论我在哪里使用我的契约接口,都不可能使用外部JAR中的类作为autowire替换吗?让我举一个例子来解释:

Spring project:
@Controller
public class MyController {
     @Autowired
     private MyInterface interface;
}

现在,实现契约接口的JAR可能是由客户端提供的,我可能事先不知道包名,它甚至可能是一个非Spring项目,所以它可能不会用@Component注释声明。

例如

public class CustomerClass implements MyInterface {
}

现在,在我的spring项目中,有没有一种方法可以注入CustomerClass来代替MyInterface?我希望我的问题很清楚。

感谢

@Paddy,关于您所关心的是否可以用传统的XML方式来实现同样的目标。以下是演示如何实现它的示例代码。注意:接口MyInterface不能以这种方式动态,因为控制器持有MySinterface

Spring应用程序上下文配置:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
   <property name="locations" value="classpath:test.properties" />
</bean>
<bean id="myInterface" class="${myinterface.impl}"></bean>

MyInterface和两个不同的实现类

package au.net.test;
public interface MyInterface {
    public String getMessage();
}
public class MyClass1 implements MyInterface{
    public String getMessage(){
        return "message from class 1";
    }
}
public class MyClass2 implements MyInterface{
    public String getMessage() {
        return "message from class 2";
    }   
}

类路径下的test.properties文件(可以使用ant脚本和maven概要文件更改属性值)

myinterface.impl=au.net.test.MyClass2

web层控制器(您可以注入基于动态bean候选者的实现类)

@Autowired
private MyInterface myInterface;

好的,我明白你的意思了。如果是这样的话,您的问题标题应该是如何通过Spring Container注入动态类型的类现在让我们谈谈解决方案。首先,您需要有某种属性来保存完全限定的类名。然后,您可以在运行时将自定义bean注册到spring容器中。

ClassPathXmlApplicationContext applicationContext = new    ClassPathXmlApplicationContext("classpath:/applicationContext*");
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
            //register your bean at runtime 
        beanFactory.registerBeanDefinition("myClass", BeanDefinitionBuilder.rootBeanDefinition("au.net.test.DynamicClass").getBeanDefinition());
            //retrieve you bean from spring container
        Object myBean = applicationContext.getBean("myClass");
            //cast to the type of your bean class or interface (be really careful)
        System.out.println(((DynamicClass)myBean).getMessage());

package au.net.test;
//this is the bean gets looked up and injected at runtime
public class DynamicClass {
    //simple method to verify it is working
    public String getMessage(){
        return "this is testing message";
    }
}

在上面的代码中,您只需要使"au.net.test"属性值驱动,而不是硬编码。

您可以将工厂bean与工厂方法一起使用

<bean id="serviceProvider" class="package.ServiceProvider">
<bean id="myInterface"
      factory-bean="serviceProvider"
      factory-method="createMyInterfaceInstance"/>
//it might or might not to be a singleton factory, depending on your requirement.
public class ServiceProvider{
  private static MyInterface myInterface= new CustomerClass();
  private ServiceProvider() {}
  public MyInterface createMyInterfaceInstance() {
    return myInterface;
  }
}

所以基本上,这里的想法是,您必须创建自己的工厂类和工厂方法来创建实例,根据您的工厂,它可能会创建singleton或prototype istance。然后把剩下的工作留给spring容器。

最新更新