給容器中註冊組件;
1:包掃描+組件標註註解(@Controller/@Service/@Repository/@Component)[自己寫的類]
2:@Bean[導入的第三方包裏面的組件]
3:@Import[快速給容器中導入一個組件]
1)、@Import(要導入到容器中的組件);容器中就會自動註冊這個組件,id默認是全類名
2)、ImportSelector:返回需要導入的組件的全類名數組;
3)、ImportBeanDefinitionRegistrar:手動註冊bean到容器中
4:使用Spring提供的 FactoryBean(工廠Bean);
1)、默認獲取到的是工廠bean調用getObject創建的對象
2)、要獲取工廠Bean本身,我們需要給id前面加一個&
&colorFactoryBean
//告訴Spring這是一個配置類
@Configuration
//掃描包
/*
@ComponentScan value:指定要掃描的包
excludeFilters = Filter[] :指定掃描的時候按照什麼規則排除那些組件
includeFilters = Filter[] :指定掃描的時候只需要包含哪些組件
FilterType.ANNOTATION:按照註解
FilterType.ASSIGNABLE_TYPE:按照給定的類型;
FilterType.ASPECTJ:使用ASPECTJ表達式
FilterType.REGEX:使用正則指定
FilterType.CUSTOM:使用自定義規則
*/
@ComponentScans(
value = {@ComponentScan(value="com.atguigu",includeFilters = {
@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})
},useDefaultFilters = false)
})
//類中組件統一設置。滿足當前條件,這個類中配置的所有bean註冊才能生效;
@Import({MyConfig2.class,MyConfig3.class})
//@Import導入組件,id默認是組件的全類名
public class MyConfig {
//給容器中註冊一個Bean;類型爲返回值的類型,id默認是用方法名作爲id
@Bean("person1")
public Person person01(){
return new Person("張三", 1);
}
//默認是單實例的
/**
* @Scope:調整作用域
* prototype:多實例的:ioc容器啓動並不會去調用方法創建對象放在容器中。每次獲取的時候纔會調用方法創建對象。
* singleton:單實例的(默認值):ioc容器啓動會調用方法創建對象放到ioc容器中。以後每次獲取就是直接從容器(map.get())獲取
* request:同一次請求創建一個實例
* session:同一個session創建一個實例
*
* 懶加載:
* 單實例bean:默認在容器啓動的時候創建對象;
* 懶加載:容器啓動不創建對象。第一次使用(獲取)Bean創建對象,並初始化;
*/
@Scope("prototype")
@Lazy
@Bean("person2")
public Person person02(){
return new Person("李四", 2);
}
/**
* @Conditional({Condition}) : 按照一定的條件進行判斷,滿足條件給容器中註冊bean
* 如果系統是windows,給容器中註冊("bill")
* 如果是linux系統,給容器中註冊("linus")
*/
@Conditional(WindowsCondition.class)
@Bean("bill")
public Person person03(){
return new Person("Bill Gates",63);
}
@Conditional(LinuxCondition.class)
@Bean("linus")
public Person person04(){
return new Person("linus", 49);
}
}
//判斷是否windows系統
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("Windows")){
return true;
}
return false;
}
}
public class Person {
//使用@Value賦值;
//1、基本數值
//2、可以寫SpEL; #{}
//3、可以寫${};取出配置文件【properties】中的值(在運行環境變量裏面的值)
@Value("張三")
private String name;
@Value("#{20-2}")
private Integer age;
@Value("${person.nickName}")
private String nickName;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", nickName=" + nickName + "]";
}
}
//判斷是否linux系統
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("linux")){
return true;
}
return false;
}
}
public static void main(String [] args){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
System.out.println("ioc容器創建完成....");
Object bean1 = applicationContext.getBean("person1");
Object bean2 = applicationContext.getBean("person2");
}
容器管理bean的生命週期
1、指定初始化和銷燬方法;
通過@Bean指定init-method和destroy-method;
2、通過讓Bean實現InitializingBean,DisposableBean 接口
InitializingBean(定義初始化邏輯),
DisposableBean(定義銷燬邏輯);
3、可以使用JSR250;
@PostConstruct:在bean創建完成並且屬性賦值完成;來執行初始化方法
@PreDestroy:在容器銷燬bean之前通知我們進行清理工作
4、BeanPostProcessor【interface】:bean的後置處理器;
在bean初始化前後進行一些處理工作;
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之後工作
@ComponentScan("com.bean")
@Configuration
public class MyConfigOfLife {
@Bean(initMethod="init",destroyMethod="detory")
public Car car(){
return new Car();
}
}
@Component
public class Car {
public Car(){
System.out.println("car constructor...");
}
public void init(){
System.out.println("car ... init...");
}
public void detory(){
System.out.println("car ... detory...");
}
}
@Component
public class Cat implements InitializingBean,DisposableBean {
public Cat(){
System.out.println("cat constructor...");
}
@Override
public void destroy() throws Exception {
System.out.println("cat...destroy...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("cat...afterPropertiesSet...");
}
}
@Component
public class Dog implements ApplicationContextAware {
//@Autowired
private ApplicationContext applicationContext;
public Dog(){
System.out.println("dog constructor...");
}
//對象創建並賦值之後調用
@PostConstruct
public void init(){
System.out.println("Dog....@PostConstruct...");
}
//容器移除對象之前
@PreDestroy
public void detory(){
System.out.println("Dog....@PreDestroy...");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
/**
* 後置處理器:初始化前後進行處理工作
* 將後置處理器加入到容器中
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
return bean;
}
}
使用@PropertySource讀取外部配置文件中的k/v保存到運行的環境變量中.加載完外部的配置文件以後使用${}取出配置文件的值.
@PropertySource(value={"classpath:/person.properties"})
@Configuration
public class MyConfigOfPropertyValues {
@Bean
public Person person(){
return new Person();
}
}
public static void main(String[]args){
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MyConfigOfPropertyValues.class);
Person person = (Person) applicationContext.getBean("person");
System.out.println(person);
ConfigurableEnvironment environment = applicationContext.getEnvironment();
String property = environment.getProperty("person.nickName");
System.out.println(property);
applicationContext.close();
}
XML配置
常用的還是在XML文件配置<context:component-scan base-package="com.demon"/>自動掃描包
在類上加以下註解
@Component是Spring中的一個通用註解,可以用於任何Bean,相當於註解的超類,如果不知道位於那個層,一般使用該註解
@Controller通常用於註解Controller,即控制層(MVC)
@Service,通常用於追註解Service類,即業務層
@Repository,通常用於註解DAO,即持久層的註解
@Value,注入基本數據類型和String類型數據的
@Scope,指定bean的作用範圍
@PostConstruct,指定某個方法爲初始化方法
@PreDestory,指定某個方法爲銷燬方法
@Bean,該註解只能寫在方法上,將方法的返回值作爲一個bean,並且放入spring容器
@Autowired
這個註解相當於在xml文件中配置的autowire="constructor/byName/byType",只不過我們這裏使用@Autowired方式註解方式,
且默認是通過類型判斷,意思就是不使用byName,和construtor。通過@Autowired註解,spring會自動去容器中查找對應的類型,
注入到該屬性中,且bean類中,使用@Autowired註解其屬性,我們可以不用提供getter,setter方法