1spring注解:@Configuration,@Bean,@ComponentScan(),@Scope
傳統(tǒng)的Spring做法是使用.xml文件來對bean進(jìn)行注入或者是配置aop、事物,這么做有兩個缺點:
1、如果所有的內(nèi)容都配置在.xml文件中,那么.xml文件將會十分龐大;如果按需求分開.xml文件,那么.xml文件又會非常多。總之這將導(dǎo)致配置文件的可讀性與可維護(hù)性變得很低。
2、在開發(fā)中在.java文件和.xml文件之間不斷切換,是一件麻煩的事,同時這種思維上的不連貫也會降低開發(fā)的效率。
為了解決這兩個問題,Spring引入了注解,通過"@XXX"的方式,讓注解與Java Bean緊密結(jié)合,既大大減少了配置文件的體積,又增加了Java Bean的可讀性與內(nèi)聚性。
?
所有的注解都是在一個工程中進(jìn)行演示、后面不懂得可以參考前面的隨筆!
開始注解的代碼編程:
?
1.工程準(zhǔn)備 Person.class public class Person { private String name;private int age; ... } 配置類: Config.class //配置類 === 配置文件xxx.xml //@Configuration是告訴Spring這是一個配置類 @Configuration public class Config {//給容器注冊一個bean,相當(dāng)于配置文件的 <bean></bean>//類型默認(rèn)是返回的類型//id默認(rèn)是方法名@Bean("per")public Person person(){return new Person("MrChengs",20);} }?測試:
ApplicationContext app = new AnnotationConfigApplicationContext(Config.class);Person p =app.getBean(Person.class);System.out.println(p); Person [name=MrChengs, age=20] 1.@Configuration 告訴sprin該類是一個配置類 所謂的配置類相當(dāng)于我們所寫的xxx.xml配置文件 2.@Bean 給容器中注入一個Bean,相當(dāng)于<bean></bean>進(jìn)行實例化一個bean 屬性: 默認(rèn)value可以不寫?
??3.@ComponentScan()
?等同于:<context:component-scan??base-package=""></context:component-scan>
?
新建四個類,分別使用:@Repository,@Service,@Controller三個注解
@Repository public class CustomerDao { } @Service public class CustomerService { } @Controller public class CustomerConteoller { }?在Config.class類中
@Configuration @ComponentScan(value="coom.MrChengs.config",excludeFilters={ @Filter(type=FilterType.ANNOTATION,classes={Repository.class})}) public class Config {@Bean("per")public Person person(){return new Person("MrChengs",20);} } @ComponentScan:?value :指定需要掃描的包
?excludeFilters :指定掃描的適合排除那些包
Filter[] excludeFilters() default {}; FilterType type() default FilterType.ANNOTATION; Class<?>[] classes() default {};?includeFilters: 指定掃描的時候只包含那些包
? ? ??在使用的時候需要添加:useDefaultFilters=false屬性
? ? ??其余屬性和excludeFilters類似
@Testpublic void test(){ApplicationContext app = new AnnotationConfigApplicationContext(Config.class);//獲取bean的nameString [] names = app.getBeanDefinitionNames();for(String name : names){System.out.println(name);}} config customerConteoller customerService per
?
關(guān)于@Filter的使用:
1.type=FilterType.ANNOTATION: 是根據(jù)注解的規(guī)則 2.type=FilterType.ASSIGNABLE_TYPE:按照給定的類型@Filter(type=FilterType.ASSIGNABLE_TYPE,classes=CustomerService.class 3.type=FilterType.ASPECTJ:使用aspectj表達(dá)式 4.type=FilterType.REGEX:使用正則表達(dá)式 5.type=FilterTyoe.CUSTOM:自定義規(guī)則?使用5進(jìn)行測試:
@ComponentScan(value="coom.MrChengs.config",includeFilters={@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class}), },useDefaultFilters=false) public class MyTypeFilter implements TypeFilter{//MetadataReader:讀取到當(dāng)前正在掃描的包信息//MetadataReaderFactory:可以獲取到其他類的任何信息public boolean match(MetadataReader arg0, MetadataReaderFactory arg1) throws IOException {//獲取當(dāng)前類的注解信息AnnotationMetadata annotationMetadata =arg0.getAnnotationMetadata();//獲取當(dāng)前正在掃描類的信息ClassMetadata classMetadata = arg0.getClassMetadata();//獲取當(dāng)前類的資源(路徑,url...)Resource resource = arg0.getResource();//獲取類的全類名//掃描到的類String className = classMetadata.getClassName();System.out.println("--->" + className);return false;} }?
在測試打印的時候 這些都是className中打印出來的 掃描到的類 --->coom.MrChengs.config.conteoller.CustomerConteoller --->coom.MrChengs.config.dao.CustomerDao --->coom.MrChengs.config.MyTypeFilter --->coom.MrChengs.config.service.CustomerService?
當(dāng)return true的時候 當(dāng)然我們可以進(jìn)行系統(tǒng)的判斷進(jìn)行放行 config customerConteoller customerDao myTypeFilter customerService?
可以把所有的@ComponentScan都寫在里面 @ComponentScans(value={@ComponentScan(value="coom.MrChengs.config",excludeFilters={@Filter(type=FilterType.ANNOTATION,classes={Repository.class})})} )?
4.@Scope? 調(diào)整作用域
Config2.java
@Configuration public class Config2 {@Bean("per")public Person person(){return new Person("MrChengs",20);} }測試
@Testpublic void test2(){ApplicationContext app = new AnnotationConfigApplicationContext(Config2.class);String [] names = app.getBeanDefinitionNames();for(String name : names){System.out.println(name);}Person p = (Person) app.getBean("per");Person p1 = (Person) app.getBean("per");System.out.println(p == p1);} config2 per true說明默認(rèn)是單實例的,只實例化一個bean
?
@Scope
* @see ConfigurableBeanFactory#SCOPE_PROTOTYPE * @see ConfigurableBeanFactory#SCOPE_SINGLETON * @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST * @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION?
//prototype??多實例的? ? 在IOC容器創(chuàng)建之后獲取對象才開始創(chuàng)建,獲取一次創(chuàng)建一次 //singleton??單例的? ?IOC容器啟動的時候就會調(diào)用對象放到IOC容器中,多次獲取也是只獲取同一個 //request? ?同一次請求 //session? ?同一個session?
@Configuration public class Config2 {//prototype 多實例的//singleton 單例的//request//session @Scope(value="prototype")@Bean("per")public Person person(){return new Person("MrChengs",20);} } config2 per false多實例情況下,獲取一次則創(chuàng)建一個實例
?
轉(zhuǎn)載于:https://www.cnblogs.com/Mrchengs/p/10108603.html
總結(jié)
以上是生活随笔為你收集整理的1spring注解:@Configuration,@Bean,@ComponentScan(),@Scope的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: webpack与babel的深奥,渣渣的
- 下一篇: 云服务器 ECS CentOS 7配置默