叫回马枪的一个原因也是希望读者对spring有过研究。在使用spring boot的时候碰到了很多注解,这让一直习惯使用xml配置形式开发的我着实脑壳疼,决定杀spring注解形式开发一个回马枪,各注解且报上名来,别以为穿上马甲我就不是认识你了。
<context:component-scan base-package="com.xxx.xxx">
@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);
}
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 {
}
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();
}
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");
}
}
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
}
样例代码,自动装配模式:
//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();
}
@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;
}