# my-spring **Repository Path**: panleiming/my-spring ## Basic Information - **Project Name**: my-spring - **Description**: No description available - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-06-26 - **Last Updated**: 2021-08-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Spring # 目录 1. spring5注解 1. 配置组件 2. spring的扩展点 1. 扫描自定义的类或注解 2. 使用Conditional注解自定义加载类 3. 实现ImportSelector接口自定义加载类 4. 实现ImportBeanDefinitionRegistrar接口自定义加载类 5. 通过FactoryBean实现Bean的注册封装 # spring5注解 ## 配置组件 | 注解名称 | 说明 | | -------------- | ------------------------------------------------------------ | | @Configuration | 把一个类作为一个IOC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean。 | | @ComponentScan | 在配置类上加上@ComponentScan注解。该注解默认会扫描该类所在的包下所有的配置类,相当于之前的\ | | @Scope | 用于指定scope作用域的(用在类上)singleton-单例 prototype-原型,多例 request-主要应用于web模块,同一次请求只创建一个实例 session-主要应用于web模块,同一个session只创建一个对象 | | @Lazy | 表示延迟初始化 只针对单例Bean起作用,默认启动容器时不创建Bean,调用时才进行创建 | | @Conditional | Spring4开始提供,它的作用是按照一定的条件进行判断,满足条件给容器注册Bean。 | | @Import | 导入外部资源 | | @PostConstruct | 用于指定初始化方法(用在方法上) | | @PreDestroy | 用于指定销毁方法(用在方法上) | | @DependsOn | 定义Bean初始化及销毁时的顺序 | # spring的扩展点 ## 扫描自定义的类或注解 ### 实现原理 实现`org.springframework.core.type.filter.TypeFilter`,然后在@Component进行filter的设置 ### 例子 **实现自动加载所有以Custom结尾的类** 编写自己的Filter类 ```java public class MyFilter implements TypeFilter { @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { // 获取当前的类信息 ClassMetadata classMetadata = metadataReader.getClassMetadata(); return classMetadata.getClassName().endsWith("Custom"); } } ``` 对@ComponentScan注解进行引用 ```java @Configuration @ComponentScan(basePackages = "com.plm.learning", useDefaultFilters = false, includeFilters = {@ComponentScan.Filter(value = MyFilter.class, type = FilterType.CUSTOM)}) public class ComponentScanConfig { } ``` 编写测试类进行测试 ```java public class SpringMain { public static void main(String[] args) { ApplicationContext act = new AnnotationConfigApplicationContext(ComponentScanConfig.class); System.out.println("测试ComponentScan注解"); String[] names = act.getBeanDefinitionNames(); Arrays.stream(names).forEach(System.out::println); } } ``` ## 使用Conditional注解自定义加载类 ### 实现原理 实现`org.springframework.context.annotation.Condition`,然后通过@Conditional进行配置条件 ### 例子 **实现根据操作系统,加载指定的类,即如果是Window操作系统,加载WindowClass类,如果是Linux操作系统,加载LinuxClass类** 编写自己的Condition类 ```java public class LinuxCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { Environment environment = conditionContext.getEnvironment(); String osName = environment.getProperty("os.name"); System.out.println(osName); if (osName.contains("Linux")) return true; return false; } } public class WindowCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { Environment environment = conditionContext.getEnvironment(); String osName = environment.getProperty("os.name"); System.out.println(osName); if (osName.contains("Window")) return true; return false; } } ``` 对Bean进行条件判断 ```java @Configuration public class ConditionalConfig { @Conditional(value = {LinuxCondition.class}) @Bean public OsClass linux() { return new LinuxClass(); } @Conditional(value = {WindowCondition.class}) @Bean public OsClass window() { return new WindowClass(); } } ``` 编写测试类测试 ```java public static void main(String[] args) { ApplicationContext act = new AnnotationConfigApplicationContext(ConditionalConfig.class); System.out.println("------------------测试Conditional注解"); OsClass osClass = act.getBean(OsClass.class); System.out.println(osClass.toString()); } ``` ## 实现ImportSelector接口自定义加载类 ### 实现原理 通过实现`org.springframework.context.annotation.ImportSelector`接口,并通过@Import注解实现自定义Bean的加载 ### 例子 **需要引入config包下的ConditionalConfig配置类,加载对应的bean** 编写自己的ImportSelector类实现 ```java public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{AImportBean.class.getName(), BImportBean.class.getName(), ConditionalConfig.class.getName()}; } } ``` 使用@Import注解引入自定义类 ```java @Configuration @Import(value = {MyImportSelector.class}) public class ImportConfig { } ``` 编写测试类测试 ```java public class SpringMain { public static void main(String[] args) { ApplicationContext act = new AnnotationConfigApplicationContext(ImportConfig.class); String[] names = act.getBeanDefinitionNames(); Arrays.stream(names).forEach(System.out::println); } } ``` ## 实现ImportBeanDefinitionRegistrar接口自定义加载类 ### 实现原理 通过实现`org.springframework.context.annotation.ImportBeanDefinitionRegistrar`接口,并通过@Import注解实现自定义Bean的加载 ### 例子 **只有IOC中存在了Father和Mother,才将Child注册到IOC容器中** 编写自己的注册类并实现ImportBeanDefinitionRegistrar接口 ```java public class MyImportBeanDefinitionRegistry implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // BeanDefinitionRegistry bean注册信息 boolean fatherFlag = registry.containsBeanDefinition(Father.class.getName()); boolean motherFlag = registry.containsBeanDefinition(Mother.class.getName()); if (fatherFlag && motherFlag) { BeanDefinition child = new RootBeanDefinition(Child.class); registry.registerBeanDefinition("child", child); } } } ``` 添加@Import注解 ```java @Configuration @Import(value = { Father.class, Mother.class, MyImportBeanDefinitionRegistry.class}) public class ImportConfig { } ``` 编写测试类测试 ```java public class SpringMain { public static void main(String[] args) { ApplicationContext act = new AnnotationConfigApplicationContext(ImportConfig.class); String[] names = act.getBeanDefinitionNames(); Arrays.stream(names).forEach(System.out::println); } } ``` ## 通过FactoryBean实现Bean的注册封装 ### 实现原理 通过实现**org.springframework.beans.factory.FactoryBean**接口,封装对Bean的注册 ### 例子 **通过FactoryBean封装Monkey类** 创建自己的FactoryBean实现类 ```java public class MonkeyFactoryBean implements FactoryBean { @Override public Monkey getObject() throws Exception { return new Monkey("Hello", "猴子"); } @Override public Class getObjectType() { return Monkey.class; } @Override public boolean isSingleton() { return true; } } ``` 使用@Bean注解声明 ```java @Configuration public class BeanConfig { @Bean public MonkeyFactoryBean monkey() { return new MonkeyFactoryBean(); } } ``` 编写测试类进行测试 ```java public class SpringMain { public static void main(String[] args) { ApplicationContext act = new AnnotationConfigApplicationContext(BeanConfig.class); System.out.println("------------------测试FactoryBean"); Monkey monkey = act.getBean("monkey", Monkey.class); System.out.println(monkey); MonkeyFactoryBean factoryBean = act.getBean("&monkey", MonkeyFactoryBean.class); System.out.println(factoryBean); } } ```