作者ntpuisbest (阿龙)
看板java
标题[问题]没有autowired会要自己new一堆很深的建构?
时间Mon May 9 01:04:49 2022
之前问过类似的问题
大概知道了autowired的好处
比如说
Spring @Autowired 搭配 @Qualifier 指定注入的Bean
重点在 依赖於介面 而不依赖於实作
这样抽换的时候就会方便很多
但是还是有一个地方不太懂
就是说如果有层层的依赖关系的话
没有autowired就会出现 一层层的new 建构子出现
但是我自己举了几个例子
并没有出现一层层 new的建构子
之前软体版有人回答过我,但是那连结已经失效了QQ
假设Service1 依赖於 Dao1 ,Dao1又依赖於Dao11和Dao22好了
以下是我的测试CODE
1. Dao11
public class Dao11 {
public void sayhi() {
System.out.println("hi");
}
}
2.Dao22
public class Dao22 {
public void sayhi2() {
System.out.println("hi fomr dao22");
}
}
3. Dao1
public class Dao1 {
// private Dao11 dao11;
Dao11 dao11=new Dao11();
Dao22 dao22=new Dao22();
public void sayhifromDao1() {
dao11.sayhi();
dao22.sayhi2();
}
}
4. Service1
public class Service1 {
Dao1 dao1=new Dao1( );
public void sasdf() {
dao1.sayhifromDao1();
}
}
5. Main Class
public class MainDriver {
public static void main(String[] args) {
Service1 service=new Service1();
service.sasdf();
}
}
我的疑惑是不管我的Service依赖了几层东西
最後都是非常乾净清爽的
一行 new Service1 ();
并且是空的建构子,就可以做到
那这样就我的理解,是不是只要我没有宣告
field在class里面
意思就是我没有宣告
// private Dao11 dao11; 在Dao1 里面
不管我的Service1 依赖多少东西 ,最後都可以用空的建构子new出来
并且保证功能正常运行
第二个问题是
怎麽样造出那些
真的会有需要 层层 new的例子
这方面想不太出来
谢谢JAVA版
这几天又一直疯狂纠结这件事....
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 36.225.243.102 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1652029491.A.B56.html
1F:→ ssccg: 你只用你自己写的程式当然觉得都用无参数建构子就好05/09 04:46
2F:→ ssccg: 假设你的Dao需要个一定得从外面传进来的DataSource05/09 04:47
3F:→ ssccg: 势必要改成这一串相依类别的建构子都要有DataSource参数05/09 04:48
4F:→ ssccg: 「所有类别都能用无参数建构子new出来」是你一厢情愿的想法05/09 04:49
5F:→ ssccg: 就算不用依赖注入,把Dao的new直接写在Service的里也不是好05/09 04:52
6F:→ ssccg: 事,这代表Dao的建构子一改你所有new到他的Service都要改05/09 04:52
7F:→ ssccg: 这就是直接依赖实作的问题,即使没有特别抽出interface,只05/09 04:55
8F:→ ssccg: 呼叫public method是只依赖於介面,呼叫到建构子是绑死实作05/09 04:56
9F:→ ntpuisbest: 晚点来看一下Data source例子,谢谢05/09 08:38
https://i.imgur.com/5Is3GmX.jpg
https://i.imgur.com/IJHRcWy.jpg
不知道你说的是不是这种例子
但看起来用getDatasouce好像也没有依赖实作的问题
可能我找的例子没很好
抱歉
※ 编辑: ntpuisbest (36.225.243.102 台湾), 05/09/2022 20:31:34
10F:→ ssccg: 你在你的Dao里面是要怎麽呼叫getDatasource? 05/09 21:17
我看他的测试程式码,并没有呼叫getDatasource这个方法,但有autowired他
是代表autowired自动会为了注入,所以呼叫getter吗?
然後@Bean注解也有发挥效用?
※ 编辑: ntpuisbest (49.216.234.222 台湾), 05/09/2022 22:24:47
https://www.796t.com/content/1549926748.html
我觉得可能跟这有关,不确定他怎麽做掉的
https://i.imgur.com/futmx4a.jpg
https://i.imgur.com/FD36yv2.jpg
※ 编辑: ntpuisbest (49.216.234.222 台湾), 05/09/2022 23:22:24
11F:→ ssccg: 那个getDatasource不是getter,是定义一个Bean (由spring的05/10 00:22
12F:→ ssccg: ApplicationContext管理的物件),spring的@Autowired或其他05/10 00:23
13F:→ ssccg: 注入方式并不是找任意类别,只会从ApplicationContext中注05/10 00:26
14F:→ ssccg: 册的Bean里找名称/类别/Qualifer符合的05/10 00:27
15F:→ ssccg: 先不谈spring怎麽做的,先集中在你一开始的问题,所以你把05/10 00:28
16F:→ ssccg: 你的Service、Dao1、Dao11写好了,现在Dao11里面要这个 05/10 00:29
17F:→ ssccg: DataSource,你main里只有Service1 service=new Service1()05/10 00:31
18F:→ ssccg: 你要怎麽改?05/10 00:31
那这样就无法是空的建构子了?
但我陷入的僵局是jdbc的连线资讯写死在
application.properties里面
如果是一般的物件,比如说是Company里面有一个member是员工好了
我还可以理解new Employee("name",age)
new Company(new Employee("name",age)
但是对於写死的,要更改只要更改
applicstion.properties就好
我写的有点乱
我知道要跟资料库连线一定要有连线资讯
所以我一定要将连线资讯注入dao
那如果说autowired在datasource上帮我注入了好了
那没有autowired这个注解,我要怎麽注入?
就我以前学的理解最早应该都是封装一个类别来get connection
差不多这样
Connection conn = DBUtils.getConn();
那如果是这样我好像也不会看到一层层的new
(高耦合)
还有依赖於dao的service如果没有autowired注解的话
是不是就会有一层层new了呢?
19F:→ ssccg: 是说你问法很像只有在找范例读、写些只有sout的测试,建议05/10 00:34
20F:→ ssccg: 先找个题目写个会动的系统,真正用过这些功能再问05/10 00:35
21F:→ ssccg: 工具是解决问题用的,你没有问题要解决,拿着工具再怎麽问05/10 00:42
22F:→ ssccg: 它哪里好用,得到答案你的感觉还是这有什麽用?05/10 00:43
23F:→ ssccg: 对你现在都在一个main就做完的需求,的确这些工具都没用05/10 00:45
因为我上班一年下来
几乎都是在application.properties里面就把database的连线设定写好,因为我们不会同
时连超过两个资料库,虽然还是有分dev跟prod
不过就只是用spring.profiles.active=xxxx而已
平常工作就是写restful api,复杂一点顶多表格多一点join
只是我这次面试下来发现很多面试官都超爱问我
spring ioc能干嘛干嘛
结果当我反问我在版上举的那些例子的时候
每个人都跟我说降低了耦合
我就会问那我这样new一个空的建构子到底跟
autowired差在哪?
几乎每个都垮(当然我面试的工作最高薪顶多70万而已) 但我还是觉得很扯
只有一个提到搭配介面还有qualifierd注解
各式各样的文章都强调
ioc跟di是spring的核心价值
但或许是因为我一直在用spring boot
平常也是无脑autowired
dao 到service
service到controller这样
总之我觉得这应该是很基本的东西
但我工作快一年掌握度还很低
让我觉得不该是这样
24F:→ gasbomb: 程式内容农场少看比较好…05/10 00:48
25F:→ gasbomb: 连等宽字型都没有的code没有看的价值05/10 00:49
※ 编辑: ntpuisbest (49.216.234.222 台湾), 05/10/2022 02:11:49
好像大概懂了
我在field里面新增了word
https://imgur.com/a/dKHqjIw
这样大概看出autowired的好处了
※ 编辑: ntpuisbest (49.216.234.222 台湾), 05/10/2022 19:59:32
26F:→ ssccg: 虽然你好像终於看出@Autowired的用处了,但是其实这只是05/12 02:42
27F:→ ssccg: @Autowired能直接用在field得到的方便,不是IoC/DI的好处05/12 02:44
28F:→ ssccg: 以你上面的code来说,其实硬要继续用无参数ctor也不是不行05/12 02:51
29F:→ ssccg: 开setter也行,甚至也可以手动reflection取代@Autowired05/12 02:53
30F:→ ssccg: spring DI的重点是根本不用自己写那段「组装」的程式码,只05/12 02:54
31F:→ ssccg: 要依照spring的惯例定义好相依关系,启动context就会自动组05/12 02:55
32F:→ ssccg: 好,组装方式可以用field/setter/ctor都支援,@Autowired不05/12 02:57
33F:→ ssccg: 过是标示而已,有参数的ctor也不是问题05/12 02:59
34F:→ ssccg: (题外话,如果只有一个ctor,不需要@Autowired标示spring也05/12 03:00
这个我知道喔,只有一个的话不用标
35F:→ ssccg: 认得,我个人习惯尽可能用这种方式,可以做到immutable,也05/12 03:12
36F:→ ssccg: 保证需要自己new的时候不会漏掉依赖,当pojo用也行) 05/12 03:22
37F:→ ssccg: 然後你说工作上没碰过复杂的组装,要不真的是micro service 05/12 03:28
38F:→ ssccg: 化/AOP用的很成功那没话说,要不就是Service其实太肥了05/12 03:30
39F:→ ssccg: 不是单纯CRUD的系统,Service常常会需要多个Service或其他05/12 03:39
40F:→ ssccg: handler、adapter...之类@Component组成的吧05/12 03:51
我的service通常里面也会需要用到其他很多crud service
其实我没写过apapter handler
但我有用spring security写过一个custom login page的系统连过mysql
就我这里的理解由於service里面都有用到dao
所以其实autowired注解真正用在dao的效用还比较大?
因为要注入连线资讯到dao里面
但在controller中应该是可以无参数子的new service()吧,手头没电脑不太确定
※ 编辑: ntpuisbest (49.216.80.89 台湾), 05/13/2022 00:25:37
41F:推 stw82: 路过 fomr可以更正成from吗? (强迫症发作) 06/08 02:20