spring boot 回马枪 之spring的ioc注解

0、spring boot 回马枪

  叫回马枪的一个原因也是希望读者对spring有过研究。在使用spring boot的时候碰到了很多注解,这让一直习惯使用xml配置形式开发的我着实脑壳疼,决定杀spring注解形式开发一个回马枪,各注解且报上名来,别以为穿上马甲我就不是认识你了。

1、注册组件

  • @Configuration
    标明这是一个配置类,以下注解均在该类中使用
  • @Bean
    注入bean 返回值就是bean配置中的class属性值,方法名或则默认value就是bean配置中的id属性值
    @Configuration、@Bean 二将出马启动AnnoatationConfigApplicationContext在IOC容器中注入了一个bean ~
  • @ComponentScan(value = “com.xxx.xxx”)
    扫描包注解:常见@Repository、@Service、@Controller、@Component等
    还可以使用@excludeFilter、@includeFilter花式指定过滤规则、正则表达式等来选择要扫描哪些包
    xml形式:
 <context:component-scan base-package="com.xxx.xxx">
  • @Scope(“singleton”)
    设置组件作用域
    singleton:单实例(默认)
    prototype : 多实例IOC启动的时候不会创建对象而是我们每次获取的时候才会创建
    request : 同一次请求创建一个实例
    session : 同一个session创建一个实例
  • @Lazy
    针对singleton单实例的bean懒加载(延迟加载),容器启动的时候不创建对象,第一次获取bean的时候再进行初始化

  • @Conditional({A.class,B.class,..})
    按照条件注册:满住条件才给容器注册bean,A类B类得实现Condition接口
    spring boot 底层大量使用的注解!可以注在类和方法上
    一个例子:
    以下代码解析:当环境中的系统是Windows的时候WindowsCondition类会返回true,则@Conditional({WindowsCondition.class})放行生成id=“bill”的bean;如果不是window系统则WindowsCondition类会返回false,则@Conditional({WindowsCondition.class})不会放行,导致不会创建被其注解的bean不会被创建。
    //判断是不是linux系统的类,实现了Conditio接口

public class LinuxCondition implements Condition {

    /**ConditionContext判断条件能使用的上下文环境
     * AnnotatedTypeMetadata注解信息
     */
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        String osname = environment.getProperty("os.name");
        if(osname.contains("Linux")) {
            return true;
        }
        return false;
   }
}

//判断是不是Windows系统的类

public class WindowsCondition implements Condition {
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //当前环境信息
        Environment environment = context.getEnvironment();
        String osname = environment.getProperty("os.name");
        if (osname.contains("Windows")) {
            return true;
        }
        return false;
    }
}

在配置类@Condition中满足属性的情况下才注册bean

    @Conditional({WindowsCondition.class})
    @Bean("bill")
    public Person person01() {
        return new Person("Bill Gates",62);
    }
    @Conditional({LinuxCondition.class})
    @Bean("linus")
    public Person person02() {
        return new Person("linus",48);
    }
  • @Import({A.class,B.class, …})
    给容器注入bean的一种方式,常用导入第三方包的bean,用来快速导入需要的组件
    使用上又有三种方式
    1. @Import({要注入的组件})
    2. ImportSelector接口:spring boot中常用,下面会写个例子
    3. ImporBeanDefinitionRegistrar接口
      实现ImportSelect接口,返回连两个实体类(全类名)
public class MyImportSelector implements ImportSelector{
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.faby.bean.Blue","com.faby.bean.Yellow"};
    }
}

配置导入,启动注解容器查看bean就能看到Blue和Yellow两个在存在容器中

@Configuration
@Import({MyImportSelector.class})
public class MainConfig {
}
  • @FactoryBean
    工厂形式注册bean
    先实现FactoryBean定义工厂类,Color为我的bean
public class ColorFactoryBean implements FactoryBean<Color> {
    public Color getObject() throws Exception {
        return new Color();
    }
    public Class getObjectType() {
        return Color.class;
    }
    public boolean isSingleton() {
        return true;
    }
}

然后在配置类中注入工厂bean

    @Bean
    public ColorFactoryBean colorFactoryBean(){
        return new ColorFactoryBean();
    }

2、生命周期-优先关注注解方式

1.@Bean(initMethod=”xxx”,destroyMethod=”xxx”)方式
//我的Bean类

public class Car {
    public Car() {
        System.out.println("------------car constructor");
    }
    public void myInit() {
        System.out.println("------------car init");
    }
    public void myDestroy() {
        System.out.println("------------car destroy");
    }
}

//我的配置类中指定初始和销毁的方法

@Configuration
public class MainConfig {
    @Bean(initMethod = "myInit",destroyMethod = "myDestroy")
    public Car car(){
        return new Car();
    }
}

2.基于配置的时候可以使用以下方式来指定bean的创建方法和销毁方法

<bean id="" init-method="" destroy-mthod=""/> 

3.让bean类实现InitializinBean和DisposableBean也可以实现管理bean生命周期
4.实现BeanPostProcessor后置处理器,spring的底层使用较多
5.@PostConstruct@PreDestroy注解形式

@Component
public class Dog {
    public Dog() {
        System.out.println("-----------dog constructor");
    }
    @PostConstruct
    public void init() {
        System.out.println("-----------dog init");
    }
    @PreDestroy
    public void destroy() {
        System.out.println("-----------dog destroy");
    }
}

3、属性赋值

  • @value @PropertySource({“classpath:/xx/xx.properties”})
    演示三种方式
public class Baby {
    @Value("佩奇")//基本数值形式
    private String name;
    @Value("${xxx}")//取额配置文件环境变量得结合@PropertySource({"classpath:/xx/xx.properties"})
    private String sex;
    @Value("#{18-8}")//SpEl形式
    private int age;

    //get and set
}

4.自动装配

  • @Autowired @Qualifier @Primary
    我在service层中需要注入dao层的bean就可以使用@Autowired,但是会遇到一个问题,我不知道我的service中注入的是哪个dao类,那么我就可以用@Primary来指定一个首选的注入到service的bean,我也可以通过使用@Qualifier来选择我需要用到的bean来注入

样例代码,自动装配模式

//service类
@Service
public class BookService {
    @Autowired
    private BookDao bookDao;
    //get and set
}

//dao类
@Repository
public class BookDao {
}

默认首选装配模式,注入的bean就是被@primary修饰的bookDao2

//service类
@Service
public class BookService {
    @Autowired
    private BookDao bookDao;
    //get and set
}

//dao类
@Repository
public class BookDao {
}

//我的配置类
@Primary
@Bean
public BookDao bookDao2() {
    return new BookDao(); 
}

明确选择装配模式注入的bean就是被@Qualifier(“bookDao”)选着的的bookDao

//service类
@Service
public class BookService {
    @Qualifier("bookDao")
    @Autowired
    private BookDao bookDao;
    //get and set
}

//dao类
@Repository
public class BookDao {
}

//我的配置类
@Primary
@Bean
public BookDao bookDao2() {
    return new BookDao(); 
}
  • @Autowired可以标记在构造器、参数、方法、属性
    1.参数位置
@Service
public class BookService {
    private BookDao bookDao;
    public void setBookDao(@Autowired BookDao bookDao) {
        this.bookDao = bookDao;
    }
    //get
}

2.标记在构造器上时如果组件只有一个有参构造器,这个参数构造器的@Autowire的可以省略
3.使用@Bean的时候方法传入了参数的 话也可以省略@Autowire

@Bean
public BookService bookService(BookDao bookDao) {
    BookService bookService = new BookService();
    bookService.setBookDao(bookDao);
    return bookService;
}
  • spring 还支持@Resource和@Inject等java规范的注解(我不想用┭┮﹏┭┮)

你可能感兴趣的:(spring,spring,spring,boot)