高清的建設(shè)工程人員查詢seo代碼優(yōu)化
目錄
前言
@Component:通用的注解!
@Bean
引入第三方的類
@Configuration
前言
首先:我們先簡單描述一下這三個的作用
@Component注解表明一個類會作為組件類,并告知Spring要為這個類創(chuàng)建bean。
@Bean注解告訴Spring這個方法將會返回一個對象,這個對象要注冊為Spring應(yīng)用上下文中的bean。通常方法體中包含了最終產(chǎn)生bean實(shí)例的邏輯。用于顯式聲明單個bean,而不是讓Spring像上面那樣自動執(zhí)行它。它將bean的聲明與類定義分離,并允許您精確地創(chuàng)建和配置bean。另外@Bean注解的方法返回值是對象,可以在方法中為對象設(shè)置屬性。
@Configuration即用來代替Spring配置文件的,它就是一個@Component組件,接收一個value值也就是bean的名字,value可以不填。
但是上面的講解都只是冰冷的概念,決定重新?lián)炱饋?#xff0c;好好研究這些配置,因?yàn)殡m說平時自己寫的時候都是機(jī)械性的,甚至是試探性的,但是還是要更深入一點(diǎn)。
為什么要先講這三個概念,是因?yàn)樗麄冎g的關(guān)系,有些你中有我我中有你,最好先有一個大概的了解。
@Component:通用的注解!
通俗的講:@Compent就是說,是標(biāo)注這個類是一個組件類,只要你想將你寫的類交給Spring容器來管理,那就可以用它!
1、@controller: controller控制器層(注入服務(wù))
2、@service : service服務(wù)層(注入dao)
3、@repository : dao持久層(實(shí)現(xiàn)dao訪問)
為什么擺出上面這三個,因?yàn)樗麄兤鋵?shí)就是@Compent,例如我們進(jìn)入到@Controller里看一下,發(fā)現(xiàn)在Controller上就有一個@Component,剩下的兩個同理
package org.springframework.stereotype;
?
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
?
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {@AliasFor(annotation = Component.class)String value() default "";
}
寫一個簡單的功能,先寫一個類,用@Compent注解上
package com.newcrud.learn;
?
import lombok.Data;
import org.springframework.stereotype.Component;
?
@Data
@Component
public class KangShiFuTwo {String name;Integer age;public void getKangShiFuTwo(){System.out.println("getKangShiFuTwo");}
}
寫一個測試類,可以用@Autowired獲取到?jīng)]說明已經(jīng)在Spring容器里了
package com.newcrud.learn;
?
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Test;
?
@SpringBootTest
?
public class KangShiFuTwoTest extends AbstractTestNGSpringContextTests {@AutowiredKangShiFuTwo kangShiFuTwo;@Testpublic void testGetKangShiFuTwo() {kangShiFuTwo.getKangShiFuTwo();}
?
}
看執(zhí)行結(jié)果
getKangShiFuTwo
@Bean
我們先看一下@Bean的源碼
package org.springframework.context.annotation;
?
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.core.annotation.AliasFor;
?
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {@AliasFor("name")String[] value() default {};
?@AliasFor("value")String[] name() default {};
?/** @deprecated */@DeprecatedAutowire autowire() default Autowire.NO;
?boolean autowireCandidate() default true;
?String initMethod() default "";
?String destroyMethod() default "(inferred)";
}
emmm,他沒有@Compent
引入第三方的類
那,我們首先創(chuàng)建一個沒有@Compent的類
package com.newcrud.learn;
?
import lombok.Data;
?
@Data
public class KangShiFuOne {String name;Integer age;public void getKangShiFuOne(){System.out.println("getKangShiFuOne");}
}
?再寫一個配置類
?import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
?
@Configuration
public class MyConfiguration {@Beanpublic KangShiFuOne getKangShiFuOneConfig(){return new KangShiFuOne();}
}
再來寫一個測試類
package com.newcrud.learn;
?
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Test;
@SpringBootTest
public class MyConfigurationTest extends AbstractTestNGSpringContextTests {@AutowiredKangShiFuOne kangShiFuOne;
?@Testpublic void testGetKangShiFuTwoConfig() {kangShiFuOne.getKangShiFuOne();}
}
結(jié)果如下
getKangShiFuOne
能被@Autowired獲取到,是因?yàn)?#64;Configuration的作用,那@Bean的作用是什么呢,因?yàn)樗幸粋€@Compent沒有的功能,那就是他可以將不在jar包里的類放到Spring容器里,比如說你在pom文件中引入的工具包,你并不能把@Compent放到里面去對不對,那你就可以通過@Bean的方式來獲取。
這個涉及到 spring boot 的自動裝載的概念,當(dāng)你的 bean 不在你 jar 包的掃描目錄下時,是沒法實(shí)例化的給 spring 管理的。
@Configuration
官方文檔描述:用@Con?guration注釋類表明其主要目的是作為bean定義的源
我們再來看一下@Configuration的源代碼,發(fā)現(xiàn)在上面也有一個@Compent,那就說明,它也有@Compent的功能
package org.springframework.context.annotation;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {@AliasFor(annotation = Component.class)String value() default "";boolean proxyBeanMethods() default true;
}
通俗的來講,這個就是代表它所注釋的類是一個配置類,但什么才是配置類呢,上面我們也看到了@Configuration好像也就是個@Compent啊,沒啥大用
那我們先來編寫兩個類
package com.newcrud.learn;import lombok.Data;@Data
public class KangShiFuFour {public KangShiFuFour(){System.out.println("getKangShiFuFour");}String name;Integer age;
}
package com.newcrud.learn;import lombok.Data;@Data
public class KangShiFuThree {public KangShiFuThree(){System.out.println("getKangShiFuThree");}String name;Integer age;
}
再來寫我們的@Configuration
package com.newcrud.learn;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyConfigurationTwo {@Beanpublic KangShiFuThree getKangShiFuThree(){return new KangShiFuThree();}@Beanpublic KangShiFuFour getKangShiFuFour(){getKangShiFuThree();return new KangShiFuFour();}
}
再寫我們的測試類
package com.newcrud.learn;import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Test;@SpringBootTest
public class MyConfigurationTwoTest extends AbstractTestNGSpringContextTests {@Testpublic void testGetKangShiFuThree() {//這個只是保留一個執(zhí)行的入口,沒有實(shí)際意義,我們要看的是啟動信息}
}
在啟動后會打印兩個類的初始化函數(shù)輸出
getKangShiFuThree
getKangShiFuFour
但是我們仔細(xì)想一下,我們是調(diào)用了兩次getKangShiFuThree的構(gòu)造函數(shù)的,但是只打印了一次,這也是他的一個功能:保持單例模式!
我們再來看一下他的另一個功能
@Con?guration類允許通過調(diào)用同一類中的其他@Bean方法來定義bean之間的依賴關(guān)
package com.newcrud.learn;import org.springframework.context.annotation.Bean;public class MyConfigurationTwo {@Beanpublic KangShiFuThree getKangShiFuThree(){return new KangShiFuThree();}@Beanpublic KangShiFuFour getKangShiFuFour(){getKangShiFuThree();//去掉@Con?guration,這里就會報(bào)錯:Method annotated with @Bean is called directly. Use dependency injection instead.,因?yàn)槲刺砑?#64;Configuration注解,導(dǎo)致@Bean之間相互調(diào)用出錯return new KangShiFuFour();}
}