<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
@Bean是一個方法級別上的註解,主要用在@Configuration註解的類裡,也可以用在@Component註解的類裡。
目的是建立一個類。當spring需要建立指定的一個類時會呼叫這個註解(@Bean)的方法。
@Data @AllArgsConstructor @NoArgsConstructor public class Info { String name; int age; }
就如同在在xml設定中新增一個類的設定。這樣spring在自動建立這個類時會呼叫設定的方法。
<bean id="info" class="zhong.test.springbootdemo.usultestdemo.demo.Info"> <property name="name" value="sjl"/> <property name="age" value="18"/> </bean>
SprignBoot中 @Bean 完美的替換了了上面的這種在xml中設定的方法。使用以下方法就能讓spring在需要自動建立Info物件時,自動呼叫這個方法。
@Configuration public class BeanInit { /** * 測試@Bean的作用 */ @Bean(name = "info") public Info getInfo(){ return new Info("gfagduis", 2343); } @Bean(name = "info1") public Info getInfo1(){ return new Info("gfagdufasfdfdais", 2343); } }
@Component public class BeanTest implements CommandLineRunner { private void getBean(){ ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanInit.class); Info info1= ctx.getBean("info",Info.class); System.out.println(info1); } @Override public void run(String... args) throws Exception { System.out.println(">>>>>>>>>>>>>>>服務啟動執行,執行載入資料等操作<<<<<<<<<<<<<"); getBean(); } }
在構造方法中設定這個值,這樣spring就會呼叫該類的建立方法來獲取這個初始化的類。
@Component public class BeanTest implements CommandLineRunner { private Info info; /** *spring建立BeanTest物件時會呼叫這個建構函式。引數是info1,所以會呼叫 @Bean(name = "info1") 註釋的方法 * */ public BeanTest (Info info1){ this.info = info1; } private void getBean2(){ System.out.println(info); } @Override public void run(String... args) throws Exception { System.out.println(">>>>>>>>>>>>>>>服務啟動執行,執行載入資料等操作<<<<<<<<<<<<<"); getBean2(); } }
在建構函式中 BeanTest (Info info1) 引數的名稱是info1.所以就呼叫 @Bean(name = “info1”) 的方法來獲取初始化物件。
結果如下:
>>>>>>>>>>>>>>>服務啟動執行,執行載入資料等操作<<<<<<<<<<<<<
Info(name=gfagdufasfdfdais, age=2343)
同時也是支援多別名設定的 例如:
@Bean(name = { "info12", "info3", "info3" }) public Info getInfo2(){ return new Info("gfa4361783ais", 2343); }
測試一下
@Component public class BeanTest implements CommandLineRunner { private Info info; private Info info1; private Info info2; /** *spring建立BeanTest物件時會呼叫這個建構函式。引數是info1,所以會呼叫 @Bean(name = "info1") 註釋的方法 * */ public BeanTest (Info info1, Info info2, Info info3){ this.info = info1; this.info1 = info2; this.info2 = info3; } private void getBean2(){ System.out.println(info); System.out.println(info1); System.out.println(info2); } @Override public void run(String... args) throws Exception { System.out.println(">>>>>>>>>>>>>>>服務啟動執行,執行載入資料等操作<<<<<<<<<<<<<"); getBean2(); } }
結果如下
>>>>>>>>>>>>>>>服務啟動執行,執行載入資料等操作<<<<<<<<<<<<<
Info(name=gfagdufasfdfdais, age=2343)
Info(name=gfa4361783ais, age=2343)
Info(name=gfa4361783ais, age=2343)
當然也可以使用 Qualifier(“xxx”) 來指定 @Bean(name = “xxx”) 中的xxx就可以呼叫對應的方法。
如果有多個初始化方法,則會根據變數名稱來獲取。
在初始化類中建立以下多個初始方法
@Configuration public class BeanInit { /** * 測試@Bean的作用 */ @Bean/*(initMethod = "init")*/ public Info getInfo(){ System.out.println("進入方法"); Info info = new Info("gfagduis", 2343); System.out.println("結束方法"); return info; } @Bean(name = "info1") public Info getInfo1(){ return new Info("gfagdufasfdfdais", 2343); } @Bean(name = { "info2", "info3", "info3" }) public Info getInfo2(){ return new Info("gfa4361783ais", 2343); } @Bean public Info info(){ return new Info("gfsdfadsfad4361783ais", 23143); }
然後在測試方法中分別用 @Autowired註釋Info類來獲取對應的物件
@Component public class BeanTest implements CommandLineRunner { //private Info info; @Autowired private Info getInfo; @Autowired private Info info1; @Autowired private Info info3; @Autowired private Info info; /*public BeanTest (Info info){ this.info = info; }*/ private void getBean(){ /*ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanInit.class); Info person = ctx.getBean("info",Info.class); System.out.println(person);*/ System.out.println(getInfo); System.out.println(info1); System.out.println(info3); System.out.println(info); } @Override public void run(String... args) throws Exception { System.out.println(">>>>>>>>>>>>>>>服務啟動執行,執行載入資料等操作<<<<<<<<<<<<<"); getBean(); } }
測試結果如下:
>>>>>>>>>>>>>>>服務啟動執行,執行載入資料等操作<<<<<<<<<<<<<
Info(name=gfagduis, age=2343)
Info(name=gfagdufasfdfdais, age=2343)
Info(name=gfa4361783ais, age=2343)
Info(name=gfsdfadsfad4361783ais, age=23143)
在使用 @Autowired 註解時,也可以與 @Qualifier(“xxx”) 指定使用哪個方法來獲取物件。
value 和 name
name 和 value 兩個屬性是相同的含義的, 在程式碼中定義了別名。 為 bean 起一個名字,如果預設沒有寫該屬性,那麼就使用方法的名稱為該 bean 的名稱
autowire
裝配方式 有三個選項
指定 bean 的裝配方式, 根據名稱 和 根據型別 裝配, 一般不設定,採用預設即可。
initMethod
bean 的初始化方法, 直接指定方法名稱即可,不用帶括號。初始方法要在對應的POHO中,也就是Info類中。
@Data @AllArgsConstructor @NoArgsConstructor public class Info { String name; int age; private void init(){ System.out.println("進入方法2"); name = "fhasjdf"; age = 12; } } @Configuration public class BeanInit { /** * 測試@Bean的作用 */ @Bean(name = "info", initMethod = "init") public Info getInfo(){ System.out.println("進入方法"); Info info = new Info("gfagduis", 2343); System.out.println("結束方法"); return info; }
最終結果、:
進入方法
結束方法
進入方法2
2019-09-24 14:57:11.917 INFO 11656 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-09-24 14:57:12.048 INFO 11656 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-09-24 14:57:12.051 INFO 11656 --- [ main] z.t.s.u.start.UsulTestStartApplication : Started UsulTestStartApplication in 1.74 seconds (JVM running for 2.246)
>>>>>>>>>>>>>>>服務啟動執行,執行載入資料等操作<<<<<<<<<<<<<
Info(name=fhasjdf, age=12)
所以最終呼叫的是init()方法來建立類。
destroyMethod
bean 的銷燬方法, 在呼叫 IoC 容器的 close() 方法時,會執行到該屬性指定的方法。不過,只是單範例的 bean 才會呼叫該方法,如果是多範例的情況下,不會呼叫該方法。
注意:
由於spring構造的物件都是單例的,所以只要是從spring ioc中獲取的物件都是同一個,他們中的屬性,即便是私有的非靜態屬性。都是公用的。
public class MyDisposableBean implements DisposableBean { public Map<String, String> map = new HashMap<>(); int i = 0; private void init(){ System.out.println("MyDisposableBean自定義初始化方法"); } private void destroyMethod(){ System.out.println("自定義銷燬方法,MyDisposableBean物件銷燬"); } public void pringt(){ System.out.println("-------------------------------"); System.out.println("i=" + i); System.out.println("map.size=" + map.size()); map.entrySet().stream().forEach(item -> System.out.println("map -> "+ item.getKey() + "---" + item.getValue())); } }
@Configuration public class BeanConfigurer { @Bean(name = "MyDisposableBean", initMethod = "init", destroyMethod = "destroyMethod") public MyDisposableBean getMyDisposableBean(){ System.out.println("MyDisposableBean構造方法"); return new MyDisposableBean(); } }
@Component public class DisposableBeanTest implements CommandLineRunner { @Override public void run(String... args) throws Exception { MyDisposableBean myDisposableBean = new MyDisposableBean(); MyDisposableBean myDisposableBean1 = new MyDisposableBean(); MyDisposableBean myDisposableBean2 = SpringContextUtils.getBean(MyDisposableBean.class); myDisposableBean2.pringt(); myDisposableBean2.map.put("1", "2"); myDisposableBean2.i = 2; MyDisposableBean myDisposableBean3 = SpringContextUtils.getBean(MyDisposableBean.class); myDisposableBean3.pringt(); myDisposableBean1.pringt(); } }
測試結果:
MyDisposableBean構造方法
MyDisposableBean自定義初始化方法
-------------------------------
i=0
map.size=0
-------------------------------
i=0
map.size=0
-------------------------------
i=2
map.size=1
map -> 1---2
-------------------------------
i=0
map.size=0
可以看出,如果是我們自己在程式中new的物件(myDisposableBean 和 myDisposableBean1),其私有屬性map和i是不變的。不相互影響。
另外兩從spring ioc中獲取的物件(myDisposableBean2 和 myDisposableBean3 )的map和i兩個屬性,是公用的。其中一個物件修改值,name另外一個物件的屬性也相應的變化
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45