Spring笔记 - 组件注册
@Bean:类注入容器
- xml方式:
<bean id="person" class="com.hrh.bean.Person">
<property name="name" value="张三"></property>
<property name="age" value="20"></property>
</bean>
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Person person = (Person) context.getBean("person");
System.out.println(person);
} - @Bean+@Configuration方式:
@Configuration//配置类==配置文件
public class BeanConfig {
@Bean
public Person person(){
return new Person("张三",20);
}
}
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
Person person = (Person)context.getBean("person");
- xml方式:
@ComponentScan:扫描类注入容器
- xml方式:
<!-- component-scan包扫描,只要标注了@Controller、@Service、@Repository、@Component的类会注入容器中
use-default-filters=false禁用默认过滤规则,使用自定义过滤规则
-->
<context:component-scan base-package="com.hrh" use-default-filters="false"/> - @ComponentScan方式:JDK1.8的ComponentScan是Repeatable的,即可以在类上定义多个@ComponentScan
@Configuration//配置类==配置文件
/**
* value:指定要扫描的包
* includeFilters:指定扫描时只需要包含哪些组件,需要使用useDefaultFilters = false使规则生效
* excludeFilters:指定扫描时按照什么规则排除哪些组件
*/
@ComponentScan(value = "com.hrh",includeFilters = {
@Filter(type = FilterType.ANNOTATION,
classes = {Controller.class})
},useDefaultFilters = false)
public class BeanConfig {
@Bean
public Person person(){
return new Person("张三",20);
}
}
//====结果====
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
beanConfig
userController
person - @ComponentScans:如果不是JDK1.8,可以使用该注解定义多个@ComponentScan
@ComponentScans({
@ComponentScan(value = "com.hrh",includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes = {Controller.class})
},useDefaultFilters = false)
})
public class BeanConfig {
@Bean
public Person person(){
return new Person("张三",20);
}
} - @Filter:过滤规则
@Configuration//配置类==配置文件
/**
* FilterType.ANNOTATION:根据注解扫描指定的类
* FilterType.ASSIGNABLE_TYPE:按照给定的类型,如果是接口类型,其实现类和子类注入容器;如果是类,本类和子类注入容器
* FilterType.ASPECTJ:使用ASPECTJ表达式
* FilterType.REGEX:使用正则表达式
* FilterType.CUSTOM:使用自定义规则,自定义实现TypeFilter接口,重写match方法
*/
@ComponentScan(value = "com.hrh", includeFilters = {
// @ComponentScan.Filter(type = FilterType.ANNOTATION,
// classes = {IUserService.class}),
// @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
// classes = {IUserService.class}),
@ComponentScan.Filter(type = FilterType.CUSTOM,classes ={MyTypeFilter.class} )
}, useDefaultFilters = false)
public class BeanConfig {
@Bean
public Person person() {
return new Person("张三", 20);
}
} public class MyTypeFilter implements TypeFilter {
/**
*
* @param metadataReader 读取到的当前正在扫描的类的信息
* @param metadataReaderFactory 可以获取到其他任何类的信息
* @return ture则将类加入容器
* @throws IOException
*/
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前类资源(类路径)
Resource resource = metadataReader.getResource();
//获取当前正在扫描的类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
String className = classMetadata.getClassName();
System.out.println("className:"+className);
if(className.contains("Controller")){
return true;
}
return false;
}
}
//====结果====
className:com.hrh.bean.Person
className:com.hrh.config.MyTypeFilter
className:com.hrh.controller.UserController
className:com.hrh.dao.UserDao
className:com.hrh.service.IUserService
className:com.hrh.service.SubUserService
className:com.hrh.service.UserService
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
beanConfig
userController
person
- xml方式:
@Scope:作用域
@Configuration
@ComponentScan(value = "com.hrh")
public class BeanConfig {
/**
* ConfigurableBeanFactory#SCOPE_PROTOTYPE:prototype
* ConfigurableBeanFactory#SCOPE_SINGLETON:singleton
* org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST:request
* org.springframework.web.context.WebApplicationContext#SCOPE_SESSION:session
* prototype:多实例,只有在获取的时候才会注入容器,每次获取都会进行创建对象注入不同的实例,每次获取的对象都不同
* singleton:单实例(默认值),ioc容器启动会调用该方法创建对象注入容器,每次获取直接中容器中拿
* request:同一次请求创建一个实例
* session:同一个session创建一个实例
*/ @Scope(value = "prototype")
@Bean
public Person person() {
System.out.println("注入容器。。。。。");
return new Person("张三", 20);
}- @Lazy:懒加载,项目启动时不创建对象注入容器,只在第一次调用时才创建对象并初始化
@Lazy
@Bean
public Person person() {
System.out.println("注入容器。。。。。");
return new Person("张三", 20);
}
- @Lazy:懒加载,项目启动时不创建对象注入容器,只在第一次调用时才创建对象并初始化
@Conditional:按照条件注入容器,实现Condition的matches()
@Configuration
@ComponentScan(value = "com.hrh")
public class BeanConfig {
@Conditional(WindowsConfig.class)
@Bean(value = "Bill")
public Person person1() {
System.out.println("创建Windows。。。。。");
return new Person("Bill", 20);
}
@Conditional(LinuxConfig.class)
@Bean(value = "Linux")
public Person person2() {
System.out.println("创建Linux。。。。。");
return new Person("Linux", 20);
}
}
public class WindowsConfig implements Condition {
/**
*
* @param context 判断条件能使用的上下文
* @param metadata 注释信息
* @return
*/
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//获取ioc使用的beanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//获取类加载器
ClassLoader classLoader = beanFactory.getBeanClassLoader();
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if("Windows 10".equals(property)){
return true;//当前系统环境是windows 10,将条件下的bean注入容器
}
return false;
}
}
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//获取ioc使用的beanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//获取类加载器
ClassLoader classLoader = beanFactory.getBeanClassLoader();
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if("Linux".equals(property)){
return true;
}
return false;
}@Import:快速导入组件进容器
public class Color {
}
@Configuration
@ComponentScan(value = "com.hrh")
@Import(Color.class)
//@Import({Color.class,Person.class})导入多个
public class BeanConfig {}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for(String beanName:beanDefinitionNames){
System.out.println(beanName);
}
}ImportSelector:实现该接口,重写selectImports()
public class MyImportSelector implements ImportSelector {
/**
*
* @param importingClassMetadata 当前标注@Import的类的全部注解信息,比如该类还标注了@Configuration也会被获取到
* @return 返回的组件全类名加入到容器中
*/
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.hrh.bean.Color","com.hrh.bean.Person"};
}
} @Configuration
@ComponentScan(value = "com.hrh")
@Import({MyImportSelector.class})
public class BeanConfig {}ImportBeanDefinitionRegistrar:实现ImportBeanDefinitionRegistrar,重写registerBeanDefinitions()
@Configuration
@Import({Color.class,MyImportBeanDefinitionRegistrar.class})
public class BeanConfig {}
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
*
* @param importingClassMetadata 当前类的注解信息
* @param registry BeanDefinition注册类,把所有需要添加到容器中的bean,调用BeanDefinitionRegistryregisterBeanDefinition注册进来
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean color = registry.containsBeanDefinition("com.hrh.bean.Color");
//容器中有Color类才将Person类进行注入
if(color) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Person.class);
registry.registerBeanDefinition("person",rootBeanDefinition);
} }
}
FactoryBean
public class MyFactoryBean implements FactoryBean<Color> {
//返回一个对象,并且该对象会注入容器
@Override
public Color getObject() throws Exception { return new Color();
} @Override
public Class<?> getObjectType() {
return Color.class;
} @Override
public boolean isSingleton() {
return true;
}
}
@Configuration
public class BeanConfig {
/**
* 1.默认获取的是MyFactoryBean调用getObject创建的对象
* 2.要获取MyFactoryBean本身,需要给id前加&,比如&myBeanFactory
*/
@Bean
public MyFactoryBean myBeanFactory(){
return new MyFactoryBean();
}
}
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
Object bean1=context.getBean("myBeanFactory");
System.out.println(bean1.getClass());
Object bean2=context.getBean("&myBeanFactory");
System.out.println(bean2.getClass());
Spring笔记 - 组件注册的更多相关文章
- Spring Framework 组件注册 之 @Component
Spring Framework 组件注册 之 @Component 写在前面 在spring大行其道的今天,对于spring的使用和掌握乃是不可缺少的必备技能.但是spring的整个体系尤为庞大,对 ...
- Spring Framework 组件注册 之 @Import
Spring Framework 组件注册 之 @Import 写在前面 向spring中注册组件或者叫javaBean是使用spring的功能的前提条件.而且spring也提供了很多种方式,让我们可 ...
- Spring Framework 组件注册 之 FactoryBean
Spring Framework 组件注册 之 FactoryBean 前言 前两篇文章介绍了如何使用@Component,@Import注解来向spring容器中注册组件(javaBean),本文将 ...
- spring注解-组件注册
一.@Configuration+@Bean @Configuration:配置类==配置文件 @Bean:给容器中注册一个Bean:类型为返回值的类型,默认是用方法名作为id @Bean(" ...
- 一、Spring之组件注册-@Configuration&@Bean给容器中注册组件
xml配置方式 首先我们创建一个实体类Person public class Person { private String name; private Integer age; private St ...
- 【建议收藏】阿里P7总结的Spring注解笔记,把组件注册讲的明明白白
环境搭建 注解的方式是通过配置类的方式来注入组件,注解注入要比XML注入的方式简单,注解注入也需要在前者的基础上,添加一个spring-context的包,也是实际开发中常用的方式. 准备所需Jar包 ...
- spring注解扫描组件注册
最近对单点系统进行微服务拆分,被各个springboot的组件注册搞得云里雾里的.(有的是通过springboot的自动配置进IOC容器的,有的是自己添加构造方法添加进IOC容器.)决定抽时间将spr ...
- 【spring 注解驱动开发】spring组件注册
尚学堂spring 注解驱动开发学习笔记之 - 组件注册 组件注册 1.@Configuration&@Bean给容器中注册组件 2.@ComponentScan-自动扫描组件&指定扫 ...
- 向Spring容器中注册组件的方法汇总小结
1.通过xml定义 <bean class=""> <property name="" value=""></ ...
随机推荐
- Jdbc批处理一点异同
同样的代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class TestBatch { public stati ...
- 关于C primer plus 的学习计划(暂停)
最近想学数据结构,但是C的基础不够好,想借着C primer plus补一下基础.怎料第一章看的还挺快,到第二章看了二十多天.现在改改阅读方式:每日在这里添加进度,然后精看例题习题和章总结,其它简略看 ...
- 深度学习环境搭建:window10+CUDA10.0+CUDNN+pytorch1.2.0
去年底入手一台联想Y7000P,配置了Nvidia GeForce GTX 1660 Ti GPU,GPU内存6G,但是因为有GPU服务器,所以一直没有在这台笔记本上跑过模型,如今经过一番折腾,终于在 ...
- ArcMap 0 (ArcGIS10.2安装)
一如GIS深似海,从此相逢是故人(这句话适合初步接触GIS的,我算是初窥门径.还是道行太浅,只是多了感慨) 前言: 1. 本人GIS专业,对于ArcGIS较为熟悉.由于专业和其它经历需要,接触过不少各 ...
- 说一说Web开发中两种常用的分层架构及其对应的代码模型
昨天妹子让我帮她解决个问题,本以为可以轻松搞定,但是打开他们项目的一瞬间,我头皮发麻.本身功能不多的一个小项目,解决方案里竟然有几十个类库.仅仅搞明白各个类库的作用,代码层次之间的引用关系就花了一个多 ...
- C. Helga Hufflepuff's Cup 树形dp 难
C. Helga Hufflepuff's Cup 这个题目我感觉挺难的,想了好久也写了很久,还是没有写出来. dp[i][j][k] 代表以 i 为根的子树中共选择了 j 个特殊颜色,且当前节点 i ...
- C - 小明系列故事――捉迷藏 HDU - 4528 bfs +状压 旅游-- 最短路+状压
C - 小明系列故事――捉迷藏 HDU - 4528 这个题目看了一下题解,感觉没有很难,应该是可以自己敲出来的,感觉自己好蠢... 这个是一个bfs 用bfs就很好写了,首先可以预处理出大明和二明能 ...
- 王颖奇 20171010129《面向对象程序设计(java)》第十四周学习总结
实验十四 Swing图形界面组件 理论知识知识点: 1.Swing和MVC设计模式2.布局管理器3.文本输入4.选择组件5.菜单6.对话框 实验时间 2018-11-29 1.实验目的与要求 (1) ...
- CSS躬行记(10)——CSS方法论
方法论是一个哲学术语,会对一系列具体的方法进行分析研究.系统总结并最终提出较为一般性的原则.CSS方法论是一种面向CSS.由个人和组织设计.已被诸多项目检验且公认有效的最佳实践.这些方法论都会涉及结构 ...
- flush方法和close方法的区别
package com.yhqtv.demo05.Writer; import java.io.FileWriter; /* * @author XMKJ yhqtv.com Email:yhqtv@ ...