Spring Beans 的公共访问修饰符和模块导出

Public Access Modifier and Module Exporting for Spring Beans

提问人:Raedwald 提问时间:9/18/2013 最后编辑:Raedwald 更新时间:11/2/2018 访问量:10871

问:

Spring bean 类(Spring 应用程序上下文设置的对象的类)必须是 Spring 创建这些对象的类吗?显然,如果你的 bean 访问不同包中的其他 bean,你的 bean 将不得不相互交互。我的问题是,你所有的 bean 类是否都必须是 .publicpublicpublic

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

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

Java 弹簧

评论


答:

29赞 Bart 9/18/2013 #1

不,并非所有类都必须是 .Spring 可以使用反射实例化 package-private 类,就像你提到的那样,没有任何问题。public

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

评论

0赞 Dcortez 4/9/2020
您能详细说明一下为什么从其他模块注入包私有 bean 不起作用吗?这对我来说并不那么明显。
1赞 Rothin Sen 8/18/2021
@Dcortez包专用类只能在同一个包中访问,但如果您尝试在不同的包中访问,则 IDE 本身会抱怨。
10赞 matsev 9/18/2013 #2

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

顺便说一句,我通常在我的 bean 实现中使用家族注解,让 Spring 使用包扫描来导入它们。@Component

例:

 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;
 }

评论

1赞 Raedwald 9/18/2013
“这允许我的实现类具有默认的访问修饰符”:但是您仍然可以选择使用包私有类,即使您的类没有实现?public interface
1赞 matsev 9/19/2013
嗯,是也不是。从 Spring 的角度来看,是的,它会为你捡起并创造豆子。例如,您可以创建一个具有包专用访问权限的类,您将获得预期的请求/响应行为。问题在于,如果您的 package-private 类用作其他包中另一个类的依赖项,那么在此之前很久就会出现编译错误。但是,这就是 Java 语言规范的设计方式,与 Spring 无关。@Controller
0赞 Jezor 10/8/2019
在这里拥有接口的唯一好处是,接口可以比服务具有更少的方法,因此您只公开要公开的内容。就我个人而言,我更喜欢组合而不是继承:有一个包私有类和一个依赖于此服务的公共外观。外观将所有调用委派给服务,并仅公开包外部所需的内容。@Service