范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

如何将一个组件注册到容器中?Bean注解一招解决

  通过组件扫描和自动注入已经大大简化了我们的开发,然而,Spring仍然不满足于此,经过版本的迭代,现在我们已经可以完全抛弃配置文件使用Spring进行开发了,一起来看看吧。 @Configuration & @Bean
  现在我们不创建Spring的配置文件,那么如何将一个组件注册到容器中呢?其实,我们仍然是需要一个配置文件的,不过这个配置文件能够以一个类的形式存在: @Configuration public class MyConfiguration { }
  @Configuration用于将一个普通的Java类变为一个Spring的配置类,现在这个类就相当于之前的配置文件了,此时如果想注册一个组件,则使用@Bean注解: @Configuration public class MyConfiguration {     @Bean     public User user() {         return new User();     } }
  这里需要注意几点,若有方法被@Bean注解标注,则该方法的返回值则为需要注册的组件,而方法名则为组件在容器中的名字,当然了,这些都需要建立在代码是写在配置类的前提下。
  如果想要修改组件的名字,可以修改方法名: @Bean public User myUser() {     return new User(); }
  若是不想修改方法名,@Bean注解也提供了修改名字的方式: @Bean(name = "myUser") public User user() {     return new User(); }
  @Bean中还有initMethod和destroyMethod属性,它们分别用于指定组件的两个生命周期方法: @Bean(name = "myUser",initMethod = "init",destroyMethod = "destroy") public User user() {     return new User(); } @ComponentScan
  @ComponentScan注解是用来完成组件扫描的,它需要标注在配置类上: @Configuration @ComponentScan("com.wwj.spring.demo") public class MyConfiguration { }
  它的作用等价于如下配置: 
  我们来聊一聊关于@ComponentScan的一些高级用法,该注解是可以在扫描时指定扫描规则的,比如我们想扫描 com.wwj.spring.demo 这个包,但是包里有一些类、或者一些注解的内容是我们不想要注册的,此时我们就可以指定扫描规则,如下:@Configuration @ComponentScan(value = "com.wwj.spring.demo", excludeFilters = {         @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {                 User.class         }) }) public class MyConfiguration { }
  在如上的配置中,excludeFilters用来配置需要排除的组件,需要借助@Filter注解,@Filter注解中的type属性用于指定以哪种方式排除组件,Spring一共提供了5种匹配方式: _ANNOTATION:_以给定的注释进行匹配 _ASSIGNABLE_TYPE:_以给定的类型进行匹配 _ASPECTJ:_以给定的AspectJ表达式匹配 _REGEX:_以给定的正则表达式匹配 _CUSTOM:_以给定的自定义规则匹配
  所以如果想要具体排除某个组件,则使用ASSIGNABLE_TYPE,如果想要排除某个注解标注的所有组件,则使用ANNOTATION: @Configuration @ComponentScan(value = "com.wwj.spring.demo", excludeFilters = {         @Filter(type = FilterType.ANNOTATION, classes = {                 Service.class         }) })
  将excludeFilters切换为includeFilters,功能将变为只扫描匹配的组件,如下: @Configuration @ComponentScan(value = "com.wwj.spring.demo", includeFilters = {         @Filter(type = FilterType.ANNOTATION, classes = {                 Service.class         }) },useDefaultFilters = false) public class MyConfiguration { }
  以上配置的作用是扫描 com.wwj.spring.demo 包下被@Service注解标注的组件,注意一点,由于Spring默认的扫描规则就是扫描所有带@Component注解的组件,所以若是想实现只扫描某个注解,则需要添加配置useDefaultFilters = false来禁用掉Spirng默认的扫描规则。
  若是想实现自定义扫描规则,也非常简单,只需实现TypeFilter接口: public class MyFilter implements TypeFilter {     @Override     public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {         // 获取完整注解元数据         AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();         // 获取类的元数据         ClassMetadata classMetadata = metadataReader.getClassMetadata();         // 获取类文件的资源引用         Resource resource = metadataReader.getResource();         // 获取类名         String className = classMetadata.getClassName();         return className.equals("user");     } }
  然后进行配置即可: @Configuration @ComponentScan(value = "com.wwj.spring.demo", includeFilters = {         @Filter(type = FilterType.CUSTOM, classes = {                 MyFilter.class         }) }, useDefaultFilters = false) public class MyConfiguration { }
  千万别忘了配置useDefaultFilters = false,此时将只能扫描到名字为user的组件。
  这些内容在配置文件中也是可以进行配置的,简单举一个例子吧:      @Scope
  @Scope用于指定组件的作用域,关于作用域在上一篇我们已经介绍过了, 所以用法其实非常简单:     @Bean     @Scope("prototype")     public User user() {         return new User();     }
  不过多介绍,但由此可以引申出一个新的注解: @Lazy ,该注解的作用是指定组件是否懒加载,默认情况下,所有组件会在容器启动的时候被创建,而如果标注@Lazy,则组件会在第一次使用时被创建。我们可以来试验一下,首先编写一个User类:public class User {     public User() {         System.out.println("user对象被创建...");     } }
  编写测试代码: public static void main(String[] args) throws Exception {     ApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class); }
  当没有添加@Lazy注解,控制台输出: user对象被创建...
  当添加了@Lazy注解,控制台没有任何输出,只有调用了 context.getBean_(_"user"_)_; User对象才会被创建。@Conditional
  @Conditional注解的功能是以指定的条件来注册组件,现在我们有两个组件: @Configuration public class MyConfiguration {      @Bean     public Watermelon watermelon() {         return new Watermelon();     }      @Bean     public Kiwi kiwi() {         return new Kiwi();     } }
  一个是夏季水果西瓜,一个是冬季水果猕猴桃,现在有一个需求是当传入参数为夏天时,就注册西瓜,当传入参数是冬天时,就注册猕猴桃,该如何实现呢?
  我们可以借助@Conditional注解来实现,首先创建类实现Condition接口: public class SummerCondition implements Condition {     @Override     public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {         String season = System.getProperty("season");         return "summer".equals(season);     } } public class WinterCondition implements Condition {     @Override     public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {         String season = System.getProperty("season");         return "winter".equals(season);     } }
  接下来就可以使用它们进行配置了: @Configuration public class MyConfiguration {      @Bean     @Conditional({SummerCondition.class})     public Watermelon watermelon() {         return new Watermelon();     }      @Bean     @Conditional({WinterCondition.class})     public Kiwi kiwi() {         return new Kiwi();     } }
  此时在虚拟机参数位置填写 -Dseason=summer ,Watermelon将被注册,当参数被修改为-Dseason=winter 时,Kiwi将被注册,SpringBoot框架的底层就大量地使用到了这个注解,不过这是题外话了,我将在后续SpringBoot系统的文章中对其再度进行介绍。@Import
  我们已经知道,目前将一个组件注册到容器中有多种方式,使用@Bean或者组件扫描都可以,然而在某些情况下,这些方式都不太方便,比如将一个第三方的组件注册到容器中,此时我们可以借助@Import注解: @Configuration @Import({Cat.class, Dog.class}) public class MyConfiguration { }
  另一种方式是使用ImportSelector,创建类实现ImportSelector接口: public class MyImportSelector implements ImportSelector {     @Override     public String[] selectImports(AnnotationMetadata importingClassMetadata) {         return new String[]{                 "com.wwj.spring.demo.entity.Cat",                 "com.wwj.spring.demo.entity.Dog"         };     } }
  将需要注册到容器中的组件全类名写到数组中,然后@Import注解只需要填写这个类的信息即可: @Configuration @Import({MyImportSelector.class}) public class MyConfiguration { }
  还有一种方式是实现ImportBeanDefinitionRegistrar接口,它与第二种方式类似,与之不同的是,这种方式可以自定义组件注册到容器中的名字: public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {     @Override     public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {         registry.registerBeanDefinition("myDog", new RootBeanDefinition(Dog.class));         registry.registerBeanDefinition("myCat", new RootBeanDefinition(Cat.class));     } }
  配置如下: @Configuration @Import({MyImportBeanDefinitionRegistrar.class}) public class MyConfiguration { }
  需要注意的是第一种和第二种方式注册的组件,其在容器中的名字是组件的全类名。 FactoryBean
  FactoryBean也是Spring提供的一种注册组件的方式,不过它比较特殊,看一个例子: public class User implements FactoryBean {     @Override     public Object getObject() throws Exception {         return new User();     }      @Override     public Class<?> getObjectType() {         return User.class;     }      @Override     public boolean isSingleton() {         return true;     } }
  这三个方法非常好理解: getObject:需要注册的组件 getObjectType:需要注册的组件类型 isSingleton:需要注册的组件是否是单例
  那有同学提出疑问了,这种方式岂不是更加麻烦了,有必要存在吗?当然有了,它牛就牛在你可以随意篡改需要注册的组件,比如: public class User implements FactoryBean {     @Override     public Object getObject() throws Exception {         return new Cat();     }      @Override     public Class<?> getObjectType() {         return Cat.class;     }      @Override     public boolean isSingleton() {         return true;     } }
  现在看似注册的是User对象,其实注册的是Cat,不信我们试试: public static void main(String[] args) throws Exception {     ApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);     Object user = context.getBean("user");     System.out.println(user.getClass()); }
  运行结果: class com.wwj.spring.demo.entity.Cat
  若是想要获得实现了FactoryBean接口的User对象本身,则需要在名字面前添加 & :public static void main(String[] args) throws Exception {     ApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);     Object user = context.getBean("&user");     System.out.println(user.getClass()); }
  运行结果: class com.wwj.spring.demo.entity.User

代工月饼翻车?极氪大定车主心意已收到,更期待极氪001随着中秋节的临近,一年一度的月饼盛宴再度登场。基于月饼的社交属性,除了传统月饼生产商外,许多非食品行业的品牌也纷纷推出联名月饼礼盒作为用户福利。不过,由于月饼本身产品及加工过程的特卧室再大也不要装大衣柜了,笨重还占地方,这样布置,家里敞亮很多人在卧室里都会装大衣柜,想要放更多的衣服和被子,但是卧室占据很多地方,而且大衣柜太笨重了,不好放置!所以即使卧室再大,也不建议装大衣柜,可以试试这样布置!家里非常敞亮!1棉被收马桶上还挂着毛巾架?快停吧!瞧人家日本主妇的做法,洁净又卫生现在很多人的生活质量提高了,那么一切都发生变化了。尤其是卫生间。卫生间的整洁很重要,走访过很多家,发现很多家里的马桶上方都放一个马桶架!真是非常不卫生的,因为厕所本来就有很多细菌,家里的细毛灰尘太多了?别心急!学会这5种方法,毛发看不见作为一个爱干净的居家主妇,每天都会为了家务活而烦恼,其实不必这么着急。只要找对正确的方法,打扫卫生很轻松。家里的细毛灰尘太多了?别心急!学会这5种方法,毛发看不见!接下来一起学习一日本人这2个小物件,中国人难以理解,看看你见过吗?日本人的家居幸福感比我们强了很多,特别是日本的主妇,他们会利用各种小物件来解决家居难题。反正日本人这2个小物件,中国人难以理解,看看你见过吗?冰箱收纳盒冰箱这个家家户户都有,但是经极氪携手中国美院,开启极氪宇宙新生物孵化计划极氪智能科技有限公司(以下简称极氪)近日宣布,将携手中国美术学院,共同开启极氪宇宙新生物孵化之旅。作为深受零世代追捧的潮流科技品牌,极氪和中国美术学院在设计美学以及极致灵感探索方面马桶三天不刷就有黄渍污垢!家政阿姨教你几招,马桶干净无异味对于马桶的清洁工作,我相信没有人愿意去做吧,特别是每次清洗马桶的时候。看到边角一圈的黄渍污垢,很多人应该跟我一样,都不愿意去面对。每次清洁马桶的时候,都要考验我的耐心,即使使劲地擦第二套房装修,厨房不妨考虑这4个先进设计,干净整洁显档次之前房子装修的时候,还不知道如何装修,只是参考非常大众的方法,跟普通家庭装修一样!装修也是普普通通的。但是不管有多么总会坚持将家里收拾干干净净!第二套房装修,厨房不妨考虑这4个先进洗衣服只知道倒洗衣液?教你正确做法,洗衣干净还卫生现在的人们生活节奏是非常快,面对自己的工作压力也很大,所以对待生活上的琐事,不想浪费太多的时间,特别是洗衣服这种小事,很多人都习惯将衣服放在洗衣机里洗,但是我们只会倒上洗衣液,剩下厨房不一定要大,这些地方若肯下功夫,看起来高大上档次干净整洁的家会让你感觉更加的舒适,我们也会有个好的心情,而厨房也不一定要很大,够用就是最好的!如果你肯在这几个地方下功夫,你就会感觉厨房像是提升一个档次一样!厨房不一定要大,这些地卫生间这4个地方不要空着,用心设计下,腾空间还显高级!真先进卫生间和其他的空间不一样!不管面积大小,卫生间的空间感总是很紧凑。而且最主要的是它里面的所有物品都是日常刚需是必不可少的。所以我们要选择合适的布置方式,这也可以提高卫生间的使用舒适
关于会计证书补贴1000元1500元2000元的通知技能提升补贴申领条件放宽啦!持会计证书可领补贴1000元至2000元!我们都知道拿下CPA或会计证书,能享受多重政府补贴,有的企业还会单独给员工发钱而现在,又有一项政策把会计证书纳大疆机甲大师教育机器人PythonAPI中文化之一枪亮枪暗之前开始整理机甲的PythonAPI,但纸上得来终觉浅,而且发现有些API与即使官方qq群的教程文档也有少许出入,于是打算逐个测试。这一系列将附上真机运行视频,以便以后直观看到最终(多图)火热出炉的大疆机甲大师教育机器人开箱组装小记2010年之后再没碰过机器人的准新手在向大疆官方确认过Python开发支持使用中文命名标识符之后(应该是独一无二的理由吧),终于下决心入手。昨日(现在半夜1点多,趁还记得清来复盘)你没见过的Java入门,使用中文例程的教程之十一活久见第四讲里,用到了Integer。parseInt方法。如果参数输错,比如啊呜,运行后会打印出一堆诡异的东西,其中有NumberFormatException,也提到啊呜。不用懂英文大疆机甲大师教育机器人PythonAPI中文化之三底盘灯效续前文大疆机甲大师教育机器人PythonAPI中文化之二LED闪烁,这一API专门设置底盘的四个LED灯效果。视频演示(友情提示有背景音请关音箱)视频加载中首先所有四处底盘LED亮你没见过的Java入门,使用中文例程的教程之之六直到一直八直到一直记得算识字量的程序么?如果要算10年,难道必须重复10行识字量(1每年翻倍数)识字量吗?用脚趾想也不可能吧。在写代码之前,不妨先构思一下该怎么算。这里多了一个输入值年限。你没见过的Java入门,使用中文例程的教程之五如果就不然七如果就不然代码说了算if(年龄20)System。out。println(没到法定婚龄!等几年再结婚吧)elseSystem。out。println(妹妹,真想嫁也拦不住你。要不你没见过的Java入门,使用中文例程的教程之九数据排排站数组第四讲里,已经用过了参数这个字符串数组。下面我们用数组给人排队人是单个的人,多加一对方括号人就成了一队人(再加一对呢?)。一队是个长度为4的数组。它的length属性就是它的长度。自制TTS引擎第0。01步Python实现拼接单字wav文件演示(文本源自小学一年级课文)我是中国人尚未找到开源和成熟的中文TTS引擎,于是先自己摸索一下。实现思路很原始,自己读一系列单字,用Audacity录成wav文件。再写个PythoJBL蓝牙无线耳机评测,戴上它让你享受运动乐趣身为一名程序员的我,平时工作比较忙,而且一坐就是一整天,总是感觉到腰酸背疼,忙里偷闲经常都会找一些时间去做运动健身,这样的话不仅可以锻炼身体也能够改善腰酸背疼的情况。不过健身运动可黑龙江省长胡昌升率团赴宝能集团总部考察,与姚振华座谈近期,黑龙江省长胡昌升率团赴宝能集团总部考察,与公司董事长姚振华座谈,深圳市委副书记时任代市长覃伟中陪同。座谈会上,胡昌升省长对宝能集团积极响应国家号召支持东北振兴的家国情怀与大企