Java Spring 问题求解

2021-11-19 18:36:06 +08:00
 gosidealone
@Component
public class ExpressOrderThreeSectionsCodeTask implements Callable {

    private String orderNo;
    private String countryCode;
    private String provinceName;
    private String cityName;
    private String districtName;
    private String address;

    @Autowired
    private IExpressOrderApiService expressOrderApiService;

    public ExpressOrderThreeSectionsCodeTask(String orderNo, String countryCode, String provinceName,
                                             String cityName, String districtName, String address) {
        this.orderNo = orderNo;
        this.countryCode = countryCode;
        this.provinceName = provinceName;
        this.cityName = cityName;
        this.districtName = districtName;
        this.address = address;
    }
...
}

代码如上,当我使用了 @Component 注解时 为什么 ExpressOrderThreeSectionsCodeTask 这个构造函数会报错,被 Spring 管理的类不能有自己的私有属性或者构造函数嘛?

2408 次点击
所在节点    Java
22 条回复
chendy
2021-11-19 18:43:40 +08:00
需要加一个无参构造方法
否则 spring 要用这个有参的构造方法构造 bean ,然而并没有这些 String bean ,于是报错
oldking24
2021-11-19 18:45:13 +08:00
我用你的代码不会报错,你是少实现了一个方法吧
gosidealone
2021-11-19 18:50:55 +08:00
@chendy 那我如果加上一个无参构造方法,我在别的地方用 new 来初始化这个对象,那我可以正常使用这个类的某个方法(这个方法调用了 autowired 的 service) ?
chendy
2021-11-19 18:57:29 +08:00
@gosidealone 不能,因为不是 spring 管理的 bean ,依赖不会注入
gosidealone
2021-11-19 19:11:22 +08:00
@chendy 可是我已经加了 component 注解了
cs419
2021-11-19 19:22:54 +08:00
这代码你就没觉着奇怪么
就算 spring 把这个对象创建出来了
countryCode cityName 必然都是 null
你再自己调用 setXxx 方法给这些属性赋值?

spring 可以给外部 bean 进行属性注入
beanFactory.autowireBean(hello);
可以自己先把对象 new 出来 再调用 beanFactory 自动注入
andyforxxx
2021-11-19 19:22:56 +08:00
@gosidealone 注解只是元数据 /标识,处理逻辑由其他类提供。不是从 IOC 获得的对象,谁会帮你完成依赖注入的工作呢?
gadfly3173
2021-11-19 19:30:30 +08:00
要自定义构造 bean 的话,一般来说是在 configuration 类里声明这个 bean ,configuration 会在启动的时候运行,把你声明的 bean 再注入到其他部分。
oneisall8955
2021-11-19 20:07:10 +08:00
应该把 orderNo 等参数封装成 entity ,方法传递这个 entity 进行业务处理
gosidealone
2021-11-19 22:00:10 +08:00
@oneisall8955 这里继承了 callable 接口,重写了 call()方法, 方法没有参数传递,entity 只能通过构造方法注入
gosidealone
2021-11-19 22:02:16 +08:00
@andyforxxx 意味着我 new 出来的对象,加什么注解都没有,spring 都不会给我注入是吧。 然后我这样不能运行的原因是 spring 创建对象也是按造构造函数来创建对象的是吧
Jtyczc
2021-11-20 05:17:14 +08:00
autowrited 上面加个 @lazy 看看
whincwu
2021-11-20 09:27:11 +08:00
构造函数注入时,如果参数列表包含基础类型(如 String ),spring 无法判断要注入的参数,此时需要显式指定参数的注入值

XML 配置,例如
<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg type="int" value="7500000"/>
<constructor-arg type="java.lang.String" value="42"/>
</bean>
aguesuka
2021-11-20 09:54:28 +08:00
你需要一个 ExpressOrderThreeSectionsCodeTaskFactory, 里面 Autowired#IExpressOrderApiService 字段, 它有一个 ExpressOrderThreeSectionsCodeTask createTask(String orderNo, String countryCode, String provinceName, String cityName, String districtName, String address) 方法. 当然这个 factory 也可以用 @\Bean 实现
andyforxxx
2021-11-20 10:49:41 +08:00
@gosidealone 当然。建议巩固下 Java 基础,Spring 也不能违背基本法的
bxb100
2021-11-20 11:08:06 +08:00
我知道了你需要的是 @Bean 这个注解
gosidealone
2021-11-20 18:50:50 +08:00
@bxb100 怎么说
bxb100
2021-11-20 19:34:09 +08:00
@gosidealone 生成 Spring 托管的 Bean 啊
gosidealone
2021-11-20 21:33:29 +08:00
@bxb100 我基础差 只学过 springboot 没有 spring 的整体概念,好多不懂
goalidea
2021-11-23 17:48:23 +08:00
@bxb100 他的答案是正解

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/816619

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX