这篇文章主要介绍了Java基础之Bean的创建、定位和使用,文中有非常详细的图文示例及代码,对正在学习java基础的小伙伴们有很好地帮助,需要的朋友可以参考下
目录
二、自动装配Bean
2.1 注册Bean
2.2 使用Bean
三、手动装配
3.1 java类
四、XML文件
五、导入配置
5.1 java类
六、导入到XML
一、前言
Bean是一个由Spring IoC容器实例化、组装和管理的对象。在 Spring 中,类的实例化、依赖的实例化、依赖的传入都交由 Spring Bean 容器控制,而不是用new方式实例化对象、通过非构造函数方法传入依赖等常规方式。这样可以减少垃圾回收对大量实例的回收工作。
在举例中使用到了三个类AAA,BBB和CCC。其中AAA和BBB是平等的两个类,可以相互调用。CCC是以BBB为构造参数的类。
二、自动装配Bean
2.1 注册Bean
为所有想要创建Bean的类添加@Component,即可在自动扫描开始时自动将类注册为Bean。
扫描默认是关闭的。要打开扫描功能,需要为包内的一个类加上注解@ComponentScan。又因为每个项目都需要配置类,所以约定注解@ComponentScan加在配置类上。
比如,为AAA类添加了注解@Component
@Component Public class AAA{ }
但是扫描功能默认是关闭的。在与AAA类同一包内添加新的类AConfig并加上@ComponentScan即可开启自动扫描功能,Spring将自动扫描该包内所有带有@Component的类。而AConfig中的内容与扫描功能无关。
【启动扫描的类名为AConfig是习惯而非规定,因为既和A有关,又和config有关】
开启自动扫描的另一种方式:XML配置
在XML文件中加入
其中XXX是AAA所在的包,即可开启对该包的自动扫描。
@ComponentScan默认扫描本包内的类注解,若想扫描其他包则需要加入参数basePackages="XXX",XXX是想要扫描的包。同理,想要指定多个包来扫描:@ComponentScan(basePackage={"XXX", "XX2"}),用大括号扩住所有包。其中basepackage可以省略,可以只写包名。
因为将字符串指定为参数的时候不安全,所以有指定包中的类来表明包的方法。将@Component中的参数换成(basePackageClass={AAA.class, BBB.class})即可扫描AAA和BBB所在的包。
单元测试时在测试类添加@ContextConfiguration(class=Aconfig.class)来指定配置类,即@ComponentScan所在的类,即可用指定配置类管理Bean。
自动形成的Bean的ID会和类名一致,就是首字母会变成小写格式。如AAA类的Bean是aAA。(其余字母不是固定大写,而是不变)
由于Bean的ID是由@Component生成的,所以在@Component中可以指定Bean的ID。@Component(”IDofA“)这样就能将AAA类的Bean的ID指定为IDofA
2.2 使用Bean
创建好Bean之后需要使用Bean
在使用Bean的方法上添加@Autowired,传入有Bean的类对象时即可实现Bean的注入。
在演示中发现,即使有注入,也要有参数传入
与不适用注解的区别在于,如果用了注入,在使用被注入的方法时无需对该方法的类实例化。
该程序中useAxe()方法使用到了Axe类,但是并没有实例化Axe类。
这里使用@Autowired,效果是使用player.play()的时候无需实例化plyaer
required=flase可以让无Bean时不报错,不推荐。
三、手动装配
使用带有注解的java类或在XML文件内显式地声明Bean的注册和注入。
3.1 java类
因为自动装配需要在源码的类上加注解,所以java类注解法适用于无法修改源码的情况。
分为两步:生成Bean和注入Bean
使用@Bean注解来生成Bean
假如AAA类要使用BBB类的对象。就要在AConfig中加入如下方法:
@Bean public BB bBB(){ return new BBB(); }
根据习惯,这个方法的名字和所需要引用的类一致来表名引用的时哪个类,只是首字母会变成小写。
@Bean会告诉spring这个方法将会返回一个对象,spring会将这个对象注册为Bean。默认情况下Bean的ID和配置中的方法同名,也可以用@Bean的name参数来修改。
@Bean(name="IDofB") public BBB bBB(){ return new BBB(); }
在配置方法中,实现了BB接口的类BBC和BBD都可以作为返回的对象被注册成Bean。
@Bean public BB otherBB(){ If(num>10) return new BBC(); Else return new BBD(); }
由此,可以在配置方法中返回不同的对象,只要有返回就能被注册成Bean。相对的,一个@Bean可以根据情况返回多个Bean实例中的一个,也会出现一种可能,多个@Bean各自满足条件返回了同一个Bean实例。
例如:
假设一个类CCC在实例化时需要一个BBB作为参数,及构造函数为
CCC(BBB){ This.bbb=BBB; }
@Bean public CCC cCC(){ return new CCC(BBB()); } @Bean public CCC anotherCCC(){ return new CCC(BBB()); }
以上两个方法都返回了同一个实例,即new CCC(BBB())。这时spring会拦截第二个BBB()产生的BBB对象,让两个CCC类方法cCC()和anotherCCC()调用同一个BBB对象。
四、XML文件
如果不指定id则id会自动变成packagename.CCC#0,再引用packagename.CCC类时会将新的Bean对象id命名为packagename.CCC#1。即,自动命名时号码自增。
spring在发现时,会自动执行类的构造方法来生成实例注册成Bean。
如果需要声明一个引用BBB的CCC
其中bBB是一个BBB类的Bean,由此讲该Bean注入到CCC。
标签可以用c命名空间来做一些简写。举一些具体的例子:
有一个引用如下
这个标签向Cdplayer类中注入了compactdisc,用c命名空间来代替标签
其中,cd-ref中的cd是Cdplayer的构造方法的参数。在调试和封装中,将代码中的参数放在XML中不安全。所以可以用代号来代替参数cd。
回归到通用符号,上例中的BBB有已经被赋值或构造时就被定义的属性。如果我们需要注入一个类BBC,且BBC在构造时需要输入参数,则可以在中输入参数。
此例的意义是:需要生成一个CCC类的Bean,且在构造CCC的时候需要三个参数。在中使用value来以此指定三个参数。
赋值的操作也可以用c命名空间来简化,用上面的具体例子来说明:
简化后的c命名空间:
其中Blankdisc类构造有title和artist两个参数,刚好对应c:的两个属性。
当然
既然标签都可以不用命名就能赋值,c命名空间也可以。
将属性名的位置排号也能实现依次赋值的作用。
来代替,会简洁很多。
property标签
第一个compact是Cdplayer的构造方法中参数的名称,第二个compact是引用的类名。简化后的p命名空间也是p:开头
五、导入配置
5.1 java类
若多个注册Bean的方法在不同的配置类中,则可以通过@import来将BConfig引入到CConfig中
例如:若BBB有一个配置类
@Configuration public class BConfig { @Bean public BBB bBB( ) { return new BBB ( ) ; } }
将BBB导入CConfig
@Configuration @import(BConfig.class) public class CConfig { @Bean public CCC cCC(BBB bBB) { return new CCC (bBB) ; } }
这样就能跨配置类使用Bean。
这种引用不是只有一对一可用。还可以定义一个新的配置类,把BConfig和CConfig都引用进去。
以上是导入用配置类生成的Bean。若要导入XML配置的Bean则需要@importResource。为配置类加上注解@importResource("classpath:Bconfig.xml")
六、导入到XML
同理,使用标签也可以实现向XML文件中导入其他的XML文件。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。