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方法

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