【问题标题】:Java 8 and Spring 4 : Use autowiring in interfaceJava 8 和 Spring 4:在接口中使用自动装配
【发布时间】:2016-01-13 22:08:25
【问题描述】:

Java 8 添加了一个新特性,通过它我们可以在接口中提供方法实现。 在 Spring 4 中有什么方法可以在接口中注入可以在方法体内部使用的 bean? 下面是示例代码

public interface TestWiring{

@Autowired
public Service service;// this is not possible as it would be static.
//Is there any way I can inject any service bean which can be used inside testWiringMethod.
default void testWiringMethod(){
  // Call method of service
  service.testService();
 }
}

【问题讨论】:

  • 你不能实例化一个接口。你将如何在其中自动装配一个字段?
  • 我想在我的方法体内使用 Spring 托管服务。一种方法是使用 ApplicationContext.getbean(") 方法。但我正在寻找 Spring 4 中的任何功能,我可以利用这些功能在接口中注入 Spring 托管 bean。接口将由某个 bean 实现。所以它应该在实现类中可用。默认情况下,由于接口的成员是静态最终的,所以我不能直接使用@autowiring。
  • Spring 中的 DI 通过在构造函数中设置依赖项(构造函数注入)或通过属性(setter 注入)来工作。在接口中,你没有构造函数,也没有实例变量(你在接口中声明的变量是static final),所以没有办法注入任何东西。
  • 你不能为此使用抽象类吗?
  • 一个可能的用例可以在实现 CRUD 存储库的 Spring Data 接口中。我正在用 Mysql 测试新的 Spring R2DBC。因此,像通常的 Spring Data Interfaces 一样,如果不提供实现,就无法编写自定义抽象方法,如 findByIdLike 和其他自定义查询。在这种情况下,我需要使用数据库客户端并使用实现编写自定义方法,可能使用新的 Java 8 默认方法。我不想编写新的接口和实现类,因为 Spring 和我的接口都将与同一个实体/表进行交互。

标签: java-8 spring-4


【解决方案1】:

这有点棘手,但如果您需要接口内部的依赖项来满足任何要求,它就可以工作。

这个想法是声明一个方法,该方法将强制实现的类提供您想要自动装配的依赖项。

这种方法的不好的一面是,如果您想提供太多的依赖项,代码将不会很漂亮,因为您需要为每个依赖项设置一个 getter。

public interface TestWiring {

   public Service getService();

   default void testWiringMethod(){
       getService().testService();
   }

}


public class TestClass implements TestWiring {

    @Autowire private Service service;

    @Override
    public Service getService() {
        return service;
    }

}

【讨论】:

  • 其实我不认为这是一个坏主意,因为它清楚地表明接口需要这些字段。
  • 1+ 用于解决方案,但对于这些情况,抽象类是更好的选择
  • 但是这是什么服务等级?这是“javax.xml.ws.Service”吗?
【解决方案2】:

您可以创建应用程序上下文的 Class utils 并在任何地方使用它,甚至不是 bean 类。

你可以有这样的代码:

public class ApplicationContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext context) {
        ApplicationContextUtil.applicationContext = context;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

}

并将其添加到您的弹簧配置中

<bean class="com.example.ApplicationContextUtil" id="applicationContextUtil"/>

现在可以在需要时轻松使用:

ApplicationContextUtil.getApplicationContext().getBean(SampleBean.class)

这个词在 web 和简单的 spring 应用程序中。

【讨论】:

  • 不使用xml怎么办?你能简单地使用@Component 吗?
  • @Please_Dont_Bully_Me_SO_Lords 不一样只是另一种声明 bean 的方式
  • 这被认为是不好的做法,因为它很难测试
  • 另外,您不需要 xml 部分。只需添加@Service 注释
猜你喜欢
  • 1970-01-01
  • 2011-01-24
  • 2012-08-13
  • 2011-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-03
  • 1970-01-01
相关资源
最近更新 更多