准备Bean
public class Bean1 {
public void Bean1() {
System.out.println("Bean1被Spring实例化");
}
}
@Component
public class Bean2 {
public void Bean2() {
System.out.println("Bean2被Spring管理了");
}
}
public class Bean3 {
public void Bean3() {
System.out.println("Bean3被Spring管理了");
}
}
@Controller // @Component派生注解
public class Controller1 {
public void Controller1() {
System.out.println("Controller1实例化被Spring管理了");
}
}
public interface Mapper1 {
}
public interface Mapper2 {
}
@Configuration
@ComponentScan(basePackages = "com.you.meet.nice.test.web.spring.beanfactorypostprocessor.component")
public class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public DataSource dataSource() {
DataSourceProperties dataSourceProperties = new DataSourceProperties();
dataSourceProperties.setUsername("root");
dataSourceProperties.setPassword("root");
dataSourceProperties.setUrl("jdbc:mysql://127.0.0.1:3306/base?useSSL=false&characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true&autoReconnect=true&failOverReadOnly=false");
return dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
/*@Bean
public MapperFactoryBean<Mapper1> mapper1(SqlSessionFactory sqlSessionFactory){
MapperFactoryBean<Mapper1> mapper1MapperFactoryBean = new MapperFactoryBean<>(Mapper1.class);
mapper1MapperFactoryBean.setSqlSessionFactory(sqlSessionFactory);
return mapper1MapperFactoryBean;
}
@Bean
public MapperFactoryBean<Mapper2> mapper2(SqlSessionFactory sqlSessionFactory){
MapperFactoryBean<Mapper2> mapper2MapperFactoryBean = new MapperFactoryBean<>(Mapper2.class);
mapper2MapperFactoryBean.setSqlSessionFactory(sqlSessionFactory);
return mapper2MapperFactoryBean;
}*/
}
ConfigurationClassPostProcessor
// GenericApplicationContext无BeanFactory后置处理器
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config", Config.class);
/**
* 处理@ComponentScan @Bean @Import @ImportResource 的后置处理器
* 不加此处理器 当前Context中只有config这一个bean
*/
applicationContext.registerBean(ConfigurationClassPostProcessor.class);
// @MapperScan功能
applicationContext.registerBean(MapperScannerConfigurer.class, beanDefinition -> {
beanDefinition.getPropertyValues().add("basePackage", "com.you.meet.nice.test.web.spring.beanfactorypostprocessor.mapper");
});
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
applicationContext.close();
Spring如何完成@ComponentScan的
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config", Config.class);
ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
if (Objects.nonNull(componentScan)) {
CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
DefaultListableBeanFactory defaultListableBeanFactory = applicationContext.getDefaultListableBeanFactory();
for (String basePackage : componentScan.basePackages()) {
//System.out.println(basePackage);
// com.you.meet.nice.test.web.spring.beanfactorypostprocessor.component -> classpath:com/you/meet/nice/test/web/spring/beanfactorypostprocessor/component/**/*.class
String path = "classpath:" + basePackage.replace(".", "/") + "/**/*.class";
//System.out.println(path);
for (Resource resource : applicationContext.getResources(path)) {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
/*System.out.println("类名:"+ metadataReader.getClassMetadata().getClassName());
System.out.println("是否有@Componenet注解:"+metadataReader.getAnnotationMetadata().hasAnnotation(Component.class.getName()));
System.out.println("是否有@Componenet派生注解:"+metadataReader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName()));*/
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
if (annotationMetadata.hasAnnotation(Component.class.getName()) ||
annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(metadataReader.getClassMetadata().getClassName())
.getBeanDefinition();
String beanName = beanNameGenerator.generateBeanName(beanDefinition, defaultListableBeanFactory);
defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinition);
}
}
}
}
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
自定义-MyComponentScanPostProcessor
public class MyComponentScanPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
@SneakyThrows
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 正规写法应该获取所有@Configuration的类
ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
if (Objects.nonNull(componentScan)) {
CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
for (String basePackage : componentScan.basePackages()) {
String path = "classpath:" + basePackage.replace(".", "/") + "/**/*.class";
for (Resource resource : pathMatchingResourcePatternResolver.getResources(path)) {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
if (annotationMetadata.hasAnnotation(Component.class.getName()) ||
annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(metadataReader.getClassMetadata().getClassName())
.getBeanDefinition();
String beanName = beanNameGenerator.generateBeanName(beanDefinition, registry);
registry.registerBeanDefinition(beanName, beanDefinition);
}
}
}
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
测试
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config", Config.class);
applicationContext.registerBean(MyComponentScanPostProcessor.class);
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
applicationContext.close();
Spring是如何完成@Bean
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config", Config.class);
CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(new ClassPathResource("com/you/meet/nice/test/web/spring/beanfactorypostprocessor/Config.class"));
Set<MethodMetadata> methods = metadataReader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata method : methods) {
String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
// System.out.println(method);
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition()
.setFactoryMethodOnBean(method.getMethodName(), "config")
// 方法参数值注入
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
if (StrUtil.isNotBlank(initMethod)) {
beanDefinitionBuilder.setInitMethodName(initMethod);
}
// 一般@Bean的bean名字都是取方法名
applicationContext.getDefaultListableBeanFactory().registerBeanDefinition(method.getMethodName(), beanDefinitionBuilder.getBeanDefinition());
}
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
System.out.println(applicationContext.getBean(SqlSessionFactoryBean.class));
自定义-MyAtBeanPostProcessor
public class MyAtBeanPostProcessor implements BeanDefinitionRegistryPostProcessor {
@SneakyThrows
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(new ClassPathResource("com/you/meet/nice/test/web/spring/beanfactorypostprocessor/Config.class"));
Set<MethodMetadata> methods = metadataReader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata method : methods) {
String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
// System.out.println(method);
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition()
.setFactoryMethodOnBean(method.getMethodName(), "config")
// 方法参数值注入
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
if (StrUtil.isNotBlank(initMethod)) {
beanDefinitionBuilder.setInitMethodName(initMethod);
}
// 一般@Bean的bean名字都是取方法名
registry.registerBeanDefinition(method.getMethodName(), beanDefinitionBuilder.getBeanDefinition());
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
测试
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config", Config.class);
applicationContext.registerBean(MyAtBeanPostProcessor.class);
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
System.out.println(applicationContext.getBean(SqlSessionFactoryBean.class));
MapperFactoryBean
@Configuration
@ComponentScan(basePackages = "com.you.meet.nice.test.web.spring.beanfactorypostprocessor.component")
public class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public DataSource dataSource() {
DataSourceProperties dataSourceProperties = new DataSourceProperties();
dataSourceProperties.setUsername("root");
dataSourceProperties.setPassword("root");
dataSourceProperties.setUrl("jdbc:mysql://127.0.0.1:3306/base?useSSL=false&characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true&autoReconnect=true&failOverReadOnly=false");
return dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
@Bean
public MapperFactoryBean<Mapper1> mapper1(SqlSessionFactory sqlSessionFactory){
MapperFactoryBean<Mapper1> mapper1MapperFactoryBean = new MapperFactoryBean<>(Mapper1.class);
mapper1MapperFactoryBean.setSqlSessionFactory(sqlSessionFactory);
return mapper1MapperFactoryBean;
}
@Bean
public MapperFactoryBean<Mapper2> mapper2(SqlSessionFactory sqlSessionFactory){
MapperFactoryBean<Mapper2> mapper2MapperFactoryBean = new MapperFactoryBean<>(Mapper2.class);
mapper2MapperFactoryBean.setSqlSessionFactory(sqlSessionFactory);
return mapper2MapperFactoryBean;
}
}
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("config", Config.class);
applicationContext.registerBean(ConfigurationClassPostProcessor.class);
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
applicationContext.close();
自定义-MyMapperPostProcessor
public class MyMapperPostProcessor implements BeanDefinitionRegistryPostProcessor {
@SneakyThrows
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:com/you/meet/nice/test/web/spring/beanfactorypostprocessor/mapper/**/*.class");
CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
AnnotationBeanNameGenerator annotationBeanNameGenerator = new AnnotationBeanNameGenerator();
for (Resource resource : resources) {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
ClassMetadata classMetadata = metadataReader.getClassMetadata();
if (classMetadata.isInterface()) {
AbstractBeanDefinition mapperFactoryBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class)
.addConstructorArgValue(classMetadata.getClassName())
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
.getBeanDefinition();
/**
* 这里BeanName不能使用mapperFactoryBeanDefinition
* 因为同名Bean会被覆盖
* 这个mapperBeanDefinition不放入Bean容器 只是用来生成Bean名字
*/
AbstractBeanDefinition mapperBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(classMetadata.getClassName()).getBeanDefinition();
String beanName = annotationBeanNameGenerator.generateBeanName(mapperBeanDefinition, registry);
registry.registerBeanDefinition(beanName, mapperFactoryBeanDefinition);
}
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
测试
GenericApplicationContext applicationContext = new GenericApplicationContext();
// 注释Config类中的MapperFactoryBean
applicationContext.registerBean("config", Config.class);
applicationContext.registerBean(ConfigurationClassPostProcessor.class);
applicationContext.registerBean(MyMapperPostProcessor.class);
applicationContext.refresh();
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
applicationContext.close();