所使用的spring的版本為:4.3.12.RELEASE
一捶朵、包掃描+組件標(biāo)注注解
這個(gè)就是我們常用的幾種注解
@Controller综看,@Service岖食,@Repository,@Component
指定相關(guān)的配置類
@Configuration //告訴spring這是一個(gè)配置類
@ComponentScan(
value = {"com.nanc"},
excludeFilters =
{
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes= {Controller.class,Service.class}),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {MyTest.class})
}, useDefaultFilters = false)
public class MainConfig {
}
@Component中excludeFilters的簡要說明
這個(gè)注解會(huì)掃描指定的包及其子包句喷,可以是一個(gè)字符串的數(shù)組
excludeFilters:指定不掃描哪些組件,它的值也是一個(gè)@ComponentScan.Filter類型的數(shù)組
可選類型有:
FilterType.ANNOTATION 按照注解
FilterType.ASSIGNABLE_TYPE 按照給定的類型
FilterType.ASPECTJ:使用ASPECTJ表達(dá)式
FilterType.REGEX:使用正則指定
FilterType.CUSTOM:使用自定義規(guī)則
二兄春、使用@Bean導(dǎo)入
package com.nanc.config;
import com.nanc.entity.Person;
import org.springframework.context.annotation.*;
@Configuration
public class MainConfig {
@Scope("prototype")
@Lazy
@Bean
public Person person(){
System.out.println("給容器中添加Person....");
return new Person(1, "haha");
}
}
@Scope注解說明:
@Scope用來調(diào)整Bean的作用域赶舆,可選取值[singleton,prototype,request,session]等
singleton:單實(shí)例的(默認(rèn)值):ioc容器啟動(dòng)會(huì)調(diào)用方法創(chuàng)建對(duì)象放到ioc容器中祭饭。以后每次獲取就是直接從容器(map.get())中拿。
prototype:多實(shí)例的:ioc容器啟動(dòng)并不會(huì)去調(diào)用方法創(chuàng)建對(duì)象放在容器中九串。每次獲取的時(shí)候才會(huì)調(diào)用方法創(chuàng)建對(duì)象猪钮;
request:同一次請(qǐng)求創(chuàng)建一個(gè)實(shí)例
session:同一個(gè)session創(chuàng)建一個(gè)實(shí)例
@Lazy
懶加載:容器啟動(dòng)不創(chuàng)建對(duì)象胆建。第一次使用(獲取)Bean創(chuàng)建對(duì)象,并初始化扑馁;
沒有此注解時(shí)腻要,單實(shí)例bean:默認(rèn)在容器啟動(dòng)的時(shí)候創(chuàng)建對(duì)象沿侈;
三市栗、使用@Import 快速給容器中導(dǎo)入一個(gè)組件
使用此注解有三種方式
1、直接導(dǎo)入實(shí)體類
package com.nanc.config;
import com.nanc.entity.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(User.class)
public class MainConfig {
}
2蛛淋、引入一個(gè)實(shí)現(xiàn)了ImportSelector的類
package com.nanc.condition;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportSelector implements ImportSelector {
/**
* AnnotationMetadata: 當(dāng)前標(biāo)注@Import注解的類的所有注釋信息
* @param importingClassMetadata
* @return 要導(dǎo)入到容器中的組件全類名
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//return new String[0];
return new String[]{"com.nanc.entity.User1", "com.nanc.entity.User2"};
}
}
package com.nanc.config;
import com.nanc.condition.MyImportSelector;
import com.nanc.entity.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({User.class,MyImportSelector.class})
public class MainConfig {
}
3褐荷、導(dǎo)入一個(gè)實(shí)現(xiàn)了ImportBeanDefinitionRegistrar接口 的類
package com.nanc.condition;
import com.nanc.entity.RainBow;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* AnnotationMetadata:當(dāng)前類的注解信息
* BeanDefinitionRegistry:BeanDefinition注冊(cè)類叛甫;
* 把所有需要添加到容器中的bean;調(diào)用
* BeanDefinitionRegistry.registerBeanDefinition手工注冊(cè)進(jìn)來
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//指定Bean定義信息萌腿;(Bean的類型抖苦,Bean。贮庞。。)
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);
//注冊(cè)一個(gè)Bean窗慎,指定bean名
registry.registerBeanDefinition("rainBow",rootBeanDefinition);
}
}
package com.nanc.config;
import com.nanc.condition.MyImportBeanDefinitionRegistrar;
import com.nanc.condition.MyImportSelector;
import com.nanc.entity.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({User.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
}
四捉邢、使用Spring提供的 FactoryBean(工廠Bean)
package com.nanc.entity;
import org.springframework.beans.factory.FactoryBean;
/**
* 創(chuàng)建一個(gè)Spring定義的FactoryBean
*/
public class ColorFactoryBean implements FactoryBean<Color> {
/**
* 返回一個(gè)Color對(duì)象伏伐,這個(gè)對(duì)象會(huì)添加到容器中
* @return
* @throws Exception
*/
@Override
public Color getObject() throws Exception {
System.out.println("----------ColorFactoryBean------------------");
return new Color();
}
@Override
public Class<?> getObjectType() {
return Color.class;
}
/**
* 控制這個(gè)bean是否是單例模式?
*
* true: 單例
* false: 多實(shí)例藐翎,每次創(chuàng)建都會(huì)獲取一個(gè)新的
* @return
*/
@Override
public boolean isSingleton() {
return true;
}
}
把上面的類放入到spring容器中(可以使用@Component注解吝镣,也是在配置類中使用@Bean進(jìn)行注入)
測(cè)試類
@Test
public void test(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
//工廠Bean獲取的是調(diào)用getObject創(chuàng)建的對(duì)象
Object bean2 = applicationContext.getBean("colorFactoryBean");
Object bean3 = applicationContext.getBean("colorFactoryBean");
System.out.println("bean的類型:"+bean2.getClass());
System.out.println(bean2 == bean3);
//前面加一個(gè)& 獲取的就是ColorFactoryBean的本身實(shí)例
Object bean4 = applicationContext.getBean("&colorFactoryBean");
System.out.println(bean4.getClass());
}