1、用的最多的一个注解搞定,最常用
- @Component
- @RestController
- @Service
2、新建config类注入bean,此方式类似于以前的xml配置。
- @Configuration标识这个类是配置类
- @Bean标识这个方法返回的对象,和以前的xml中的bean一样
配置类
package com.example.config;
import com.example.dto.Teacher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig {
@Bean
public Teacher getTeacher(){
return new Teacher();
}
}
Teacher类
package com.example.dto;
import lombok.Data;
@Data
public class Teacher {
private int id;
private String name;
private int age;
}
3、Import注解导入,可以理解为嵌套,以前用xml的时候可以嵌套,注解也支持嵌套
- 可以嵌套在启动类上
- 可以嵌套在config类上
dog类
package com.example.dto;
import lombok.Data;
@Data
public class Dog {
private int id;
private String name;
private int age;
}
引入dog类1
package com.example.config;
import com.example.dto.Dog;
import com.example.dto.Teacher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(Dog.class)
public class MyConfig {
@Bean
public Teacher getTeacher(){
return new Teacher();
}
}
引入dog类2
package com.example;
import com.example.dto.Dog;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
@SpringBootApplication
@MapperScan("com.example.dao")
@Import(Dog.class)
public class SpringbootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisApplication.class, args);
}
}
4、@Import + ImportSelector
- 实现ImportSelector接口的selectImports方法
package com.example.config;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.example.dto.Cat"};
}
}
- 配置类引入
@Configuration
@Import({Dog.class,MyImportSelector.class})
5、@Import + ImportBeanDefinitionRegistrar
- 实现 ImportBeanDefinitionRegistrar 接口中的方法
package com.example.config;
import com.example.dto.Tree;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 构建一个beanDefinition, 可以简单理解为bean的定义.
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Tree.class).getBeanDefinition();
// 将beanDefinition注册到Ioc容器中.
registry.registerBeanDefinition("tree", beanDefinition);
}
}
- 配置类引入
@Configuration
@Import({Dog.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
6、@Import + DeferredImportSelector
- DeferredImportSelector 它是 ImportSelector 的子接口
package com.example.config;
import com.example.dto.Apple;
import org.springframework.context.annotation.DeferredImportSelector;
import org.springframework.core.type.AnnotationMetadata;
public class MyDeferredImportSelector implements DeferredImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{Apple.class.getName()};
}
}
- 引入配置
@Configuration
@Import({Dog.class,MyImportSelector.class,MyDeferredImportSelector.class})
7、使用FactoryBean接口
FactoryBean接口和BeanFactory千万不要弄混了,从名字其实可以大概的区分开,FactoryBean, 后缀为bean,那么它其实就是一个bean, BeanFactory,顾名思义 bean工厂,它是IOC容器的顶级接口,这俩接口都很重要。
package com.example.config;
import com.example.dto.Bike;
import org.springframework.beans.factory.FactoryBean;
public class BikeFactoryBean implements FactoryBean<Bike> {
@Override
public Bike getObject() throws Exception {
return new Bike();
}
@Override
public Class<?> getObjectType() {
return Bike.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
- 引入这里没有引入Bike直接引入BikeFactoryBean
@Configuration
@Import({BikeFactoryBean.class,Dog.class,MyImportSelector.class})
public class MyConfig
8、使用 BeanDefinitionRegistryPostProcessor
其实这种方式也是利用到了 BeanDefinitionRegistry,在Spring容器启动的时候会执行 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法,大概意思就是等beanDefinition加载完毕之后,对beanDefinition进行后置处理,可以在此进行调整IOC容器中的beanDefinition,从而干扰到后面进行初始化bean。
package com.example.config;
import com.example.dto.Cup;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Cup.class).getBeanDefinition();
registry.registerBeanDefinition("cup", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
- 引入配置
@Configuration
@Import({MyBeanDefinitionRegistryPostProcessor.class})
public class MyConfig {
总结:
向spring容器中加入bean的几种方式(5大类8小类):
- @Configuration + @Bean
- @ComponentScan + @Component
- @Import 配合接口进行导入
- 使用FactoryBean。
- 实现BeanDefinitionRegistryPostProcessor进行后置处理。