Spring--IoC註解使用小結

 給容器中註冊組件;
  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方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章