【问题标题】:Public Access Modifier and Module Exporting for Spring BeansSpring Beans 的公共访问修饰符和模块导出
【发布时间】:2013-09-23 00:00:57
【问题描述】:

Spring bean 类,Spring 应用程序上下文设置的对象的类,必须是public 类,Spring 才能创建这些对象?显然,如果 您的 bean 访问您在不同包中的其他 bean,则您的 bean 必须是 public 才能相互交互。我的问题是所有您的 bean 类是否必须是 public

由于 Spring 代码本身与您的代码所在的包位于不同的包中,因此从概念上讲,Spring 正在做一些应该要求 public 访问您的类的事情。另一方面,Spring 使用反射来创建 bean,因此它可能不需要你的类是 public

除了包访问类型之外,从 Java 9 开始我们还有 Java 模块。如果将类放在模块中,是否需要公开并从模块中导出它们?

【问题讨论】:

    标签: java spring


    【解决方案1】:

    不,并非所有课程都必须是public。 Spring可以像你提到的那样使用反射来实例化包私有类而没有任何问题..

    如果包私有 bean 由 IoC 容器管理并由同一包中的类使用,则没有问题。仅当您尝试跨包连接该 bean 时才会出现问题。这当然很明显。

    【讨论】:

    • 您能否详细说明为什么从其他模块注入包私有 bean 不起作用?这对我来说不是那么明显。
    • @Dcortez 包私有类只能在同一个包中访问,如果您尝试在不同的包中访问,您的 IDE 本身会报错。
    【解决方案2】:

    我总是努力让我的 bean 实现接口,并且让其他 bean 依赖于接口而不是实现类。为了回答您的问题,这允许我的实现类具有默认访问修饰符,这具有很好的副作用,即如果它们位于其他包中,其他 bean 不会意外访问它们。

    旁注,我通常在我的 bean 实现上使用 @Component 系列注解,并让 Spring 使用包扫描来导入它们。

    例子:

     package com.example.service;
    
     public interface SomeService {}
    

    实施:

     package com.example.service.impl;
    
     @Service
     class SomeServiceImpl {}
    

    其他依赖第一个接口的类:

     package com.example.other.impl;
    
     @Component
     class OtherServiceImpl implements OtherService {
    
         @Autowired
         private SomeService someService;
     }
    

    【讨论】:

    • “允许我的实现类有默认的访问修饰符”:但你仍然可以选择包私有类,即使你的类没有实现@987654325 @?
    • 嗯,是的,也不是。从 Spring 的角度来看,是的,它会为您拾取并创建 bean。例如,您可以创建一个具有包私有访问权限的@Controller 类,您将获得预期的请求/响应行为。问题是,如果您的包私有类被用作其他包中另一个类的依赖项,那么您将在此之前很久就会收到编译错误。但是,Java 语言规范就是这样设计的,与 Spring 无关。
    • 这里有一个接口的唯一好处是接口可以比服务有更少的方法,所以你只暴露你想要暴露的东西。就个人而言,我更喜欢组合而不是继承:有一个包私有 @Service 类和一个依赖于该服务的公共外观。外观将所有调用委托给服务,并仅公开包外需要的内容。
    猜你喜欢
    • 2011-01-31
    • 2019-07-15
    • 2017-11-11
    • 2017-08-11
    • 2017-01-03
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多