V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gosidealone
V2EX  ›  Java

Java Spring 问题求解

  •  
  •   gosidealone · 2021-11-19 18:36:06 +08:00 · 2417 次点击
    这是一个创建于 1107 天前的主题,其中的信息可能已经有所发展或是发生改变。
    @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 管理的类不能有自己的私有属性或者构造函数嘛?

    第 1 条附言  ·  2021-11-20 19:06:49 +08:00
    V 友们,非常感谢,我大概明白了,通过 new 初始化的类,autowired 注入没用的,只能通过构造函数来注入 service 之类的
    22 条回复    2021-11-27 11:54:37 +08:00
    chendy
        1
    chendy  
       2021-11-19 18:43:40 +08:00
    需要加一个无参构造方法
    否则 spring 要用这个有参的构造方法构造 bean ,然而并没有这些 String bean ,于是报错
    oldking24
        2
    oldking24  
       2021-11-19 18:45:13 +08:00
    我用你的代码不会报错,你是少实现了一个方法吧
    gosidealone
        3
    gosidealone  
    OP
       2021-11-19 18:50:55 +08:00 via iPhone
    @chendy 那我如果加上一个无参构造方法,我在别的地方用 new 来初始化这个对象,那我可以正常使用这个类的某个方法(这个方法调用了 autowired 的 service) ?
    chendy
        4
    chendy  
       2021-11-19 18:57:29 +08:00
    @gosidealone 不能,因为不是 spring 管理的 bean ,依赖不会注入
    gosidealone
        5
    gosidealone  
    OP
       2021-11-19 19:11:22 +08:00 via iPhone
    @chendy 可是我已经加了 component 注解了
    cs419
        6
    cs419  
       2021-11-19 19:22:54 +08:00
    这代码你就没觉着奇怪么
    就算 spring 把这个对象创建出来了
    countryCode cityName 必然都是 null
    你再自己调用 setXxx 方法给这些属性赋值?

    spring 可以给外部 bean 进行属性注入
    beanFactory.autowireBean(hello);
    可以自己先把对象 new 出来 再调用 beanFactory 自动注入
    andyforxxx
        7
    andyforxxx  
       2021-11-19 19:22:56 +08:00
    @gosidealone 注解只是元数据 /标识,处理逻辑由其他类提供。不是从 IOC 获得的对象,谁会帮你完成依赖注入的工作呢?
    gadfly3173
        8
    gadfly3173  
       2021-11-19 19:30:30 +08:00 via Android
    要自定义构造 bean 的话,一般来说是在 configuration 类里声明这个 bean ,configuration 会在启动的时候运行,把你声明的 bean 再注入到其他部分。
    oneisall8955
        9
    oneisall8955  
       2021-11-19 20:07:10 +08:00 via Android
    应该把 orderNo 等参数封装成 entity ,方法传递这个 entity 进行业务处理
    gosidealone
        10
    gosidealone  
    OP
       2021-11-19 22:00:10 +08:00
    @oneisall8955 这里继承了 callable 接口,重写了 call()方法, 方法没有参数传递,entity 只能通过构造方法注入
    gosidealone
        11
    gosidealone  
    OP
       2021-11-19 22:02:16 +08:00
    @andyforxxx 意味着我 new 出来的对象,加什么注解都没有,spring 都不会给我注入是吧。 然后我这样不能运行的原因是 spring 创建对象也是按造构造函数来创建对象的是吧
    Jtyczc
        12
    Jtyczc  
       2021-11-20 05:17:14 +08:00 via iPhone
    autowrited 上面加个 @lazy 看看
    whincwu
        13
    whincwu  
       2021-11-20 09:27:11 +08:00 via Android
    构造函数注入时,如果参数列表包含基础类型(如 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
        14
    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
        15
    andyforxxx  
       2021-11-20 10:49:41 +08:00
    @gosidealone 当然。建议巩固下 Java 基础,Spring 也不能违背基本法的
    bxb100
        16
    bxb100  
       2021-11-20 11:08:06 +08:00 via Android
    我知道了你需要的是 @Bean 这个注解
    gosidealone
        17
    gosidealone  
    OP
       2021-11-20 18:50:50 +08:00 via iPhone
    @bxb100 怎么说
    bxb100
        18
    bxb100  
       2021-11-20 19:34:09 +08:00
    @gosidealone 生成 Spring 托管的 Bean 啊
    gosidealone
        19
    gosidealone  
    OP
       2021-11-20 21:33:29 +08:00
    @bxb100 我基础差 只学过 springboot 没有 spring 的整体概念,好多不懂
    goalidea
        20
    goalidea  
       2021-11-23 17:48:23 +08:00
    @bxb100 他的答案是正解
    gosidealone
        21
    gosidealone  
    OP
       2021-11-23 20:25:37 +08:00
    @goalidea 在哪里加?怎么加?
    goalidea
        22
    goalidea  
       2021-11-27 11:54:37 +08:00
    @gosidealone 看官方文档
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1007 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 23:05 · PVG 07:05 · LAX 15:05 · JFK 18:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.