博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring中XML,注解,JavaConfig如何选择
阅读量:5813 次
发布时间:2019-06-18

本文共 4687 字,大约阅读时间需要 15 分钟。

前言

Spring的IOC极大的方便了我们的编程,当我们需要某个对象的时候,不在需要自己去new,只要告诉Spring一声,Spring就会把我们所需要的类准备好,就像你原来出门要穿外套时,你得先跑到衣柜前取出衣服,然后自己穿上。现在好了,你结婚了,只要跟你的另一半说一声,她就会心领神会,把衣服给你拿过来,然后帮你穿上,是不是感觉很爽?Spring有三种配置方法,这三种配置方式如何选择?先看一下这三种配置方式

XML

applicationContext.xml

复制代码

BraveKnight

public class BraveKnight {    private Weapon weapon;    public BraveKnight(Weapon weapon) {        this.weapon = weapon;    }    public Weapon getWeapon() {        return weapon;    }}复制代码

Weapon

public class Weapon {    private String type;    public String getType() {        return type;    }    public void setType(String type) {        this.type = type;    }}复制代码
public class Main {    public static void main(String[] args) {        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");        BraveKnight knight = context.getBean(BraveKnight.class);        // knife        System.out.println(knight.getWeapon().getType());        context.close();    }}复制代码

这样一个Spring项目就完成了,可以用spring的test模块,进行测试

@RunWith(SpringJUnit4ClassRunner.class)// 多个文件时可用locations = {
"", ""}@ContextConfiguration(locations = "classpath*:/applicationContext.xml")public class XMLTest { @Autowired BraveKnight braveKnight; @Test public void test() { // knife System.out.println(braveKnight.getWeapon().getType()); }}复制代码

用XML形式可以在配置文件中,配置我们自己写的类和外部库的类,Spring通过反射可以把这些类都创建出来,并由Spring管理,在你需要的时候给你

注解

BraveKnight

@Componentpublic class BraveKnight {    @Autowired    private Weapon weapon;    public Weapon getWeapon() {        return weapon;    }}复制代码

Weapon

@Componentpublic class Weapon {    @Value("knife")    // 这个值可以从外部配置文件中通过@Value注解读取到    private String type;    public String getType() {        return type;    }    public void setType(String type) {        this.type = type;    }}复制代码

MyConfig

@Configuration// 如果不配置扫描的路径,默认扫描配置类所在的包及其子包下面的所有类@ComponentScanpublic class MyConfig {}复制代码
public class Main {    public static void main(String[] args) {        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();        context.register(MyConfig.class);        context.refresh();        BraveKnight knight = context.getBean(BraveKnight.class);        // knife        System.out.println(knight.getWeapon().getType());        context.close();    }}复制代码
@RunWith(SpringJUnit4ClassRunner.class)// 从类中读取配置@ContextConfiguration(classes = MyConfig.class)public class AnnotaionTest {    @Autowired    BraveKnight braveKnight;    @Test    public void test() {        // knife        System.out.println(braveKnight.getWeapon().getType());    }}复制代码

JavaConfig

在我们自己的类上,我们可以加@Component注解让Spring来管理,如果是第三方jar包的类呢?它的类上并不会加@Component啊,如果不想用XML来生成第三方jar包的类,JavaConfig在这个时候就派上用场了,接着上面的例子,假如Weapon这个类是第三方jar包的类,则可以通过如下形式让Spring管理

@Configuration// 如果不配置扫描的路径,默认扫描配置类所在的包及其子包下面的所有类// 可以通过属性basePackages = {
""}指定扫描的包@ComponentScan()public class MyConfig { // name属性默认是方法名,自己可以指定 @Bean(name = "weapon") public Weapon weapon() { Weapon weapon = new Weapon(); weapon.setType("knife"); return weapon; }}复制代码
  1. XML配置修改后不用重新编译,可以用于经常切换实现类的对象
  2. 注解用起来非常地简洁,代码量十分少,因此是项目的第一选择
  3. 当需要注入代码不是自己维护的第三方jar包中的类时,或者需要更为灵活地注入,比如说需要调用某个接口,查询数据,然后把这个数据赋值给要注入的对象,那么这时候就需要用到Java Config

后记

说一个我在用Spring集成Storm遇到的一个有意思的问题,一般想让外部库的类让Spring管理的方法,只要用XML或者JavaConfig配置即可,我项目中有一个ClassA需要继承Storm中的一个ClassB,但是ClassB是一个抽象类,不能在XML中配置,也不能在JavaConfig中创建出来,直接在ClassA上加上@Component注解,并不能让Spring管理ClassA,因为ClassB Spring管理不到,Spring不能管理ClassA,这样就会导致ClassC注入失败

@Componentpublic class ClassA extends ClassB {    @Autowired    ClassC classC;}复制代码

可能会有人想,直接new出来不就行了,奈何ClassC是如下形式

@Componentpublic class ClassC{    @Autowired    ClassD classD;}复制代码

直接new出来,ClassD就不会被Spring注入进去,怎么办?回头看在启动类,这个类也没有被Spring管理,是怎么取到对象的?是从context中通过getBean方法拿的,但是在其他的类中怎么获取到context,其实Spring提供了一系列Aware接口,只要实现这些接口,就能获取到要东西,我们只要实现ApplicationContextAware接口,就可以获取到context,为了方便我直接封装了一个工具类,通过

SpringHellper.get(ClassC.class)复制代码

即可获取Spring管理的ClassC,并能在ClassA中愉快的使用了

@Componentpublic class SpringHelper implements ApplicationContextAware {    private static ApplicationContext context;    public static ApplicationContext getApplicationContext() {        return context;    }        public static 
T getBean(Class
requiredType) { return context.getBean(requiredType); } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { context = applicationContext; }}复制代码

注意要加上Component注解,这样在Spring启动后这个类的context属性就被填充进来了

参考博客

[1]https://zhuanlan.zhihu.com/p/29938139 [2]https://www.cnblogs.com/hedongfei/p/7899775.html

欢迎关注

喜欢本文的朋友们,欢迎关注公众号Kruskal,收看更多精彩内容

你可能感兴趣的文章
Cocos2dx 3.0开发环境的搭建--Eclipse建立在Android工程
查看>>
iOS人脸识别核心代码(备用)
查看>>
基本概念复习
查看>>
C++:成员运算符重载函数和友元运算符重载函数的比较
查看>>
[Polymer] Introduction
查看>>
【iCore3 双核心板】例程三十:U_DISK_IAP_FPGA实验——更新升级FPGA
查看>>
前端技术的发展和趋势
查看>>
Android文件下载之进度检测
查看>>
重构第10天:提取方法(Extract Method)
查看>>
吐血整理 Delphi系列书籍 118本(全)
查看>>
Android Fragment使用(四) Toolbar使用及Fragment中的Toolbar处理
查看>>
解决pycharm在ubuntu下搜狗输入法一直固定在左下角的问题
查看>>
“Info.plist” couldn’t be removed
查看>>
Linux创建系统用户
查看>>
多线程day01
查看>>
JSON path
查看>>
Win8 Metro(C#)数字图像处理--2.43图像马赛克效果算法
查看>>
动画库NineOldAndroids
查看>>
react-native 模仿原生 实现下拉刷新/上拉加载更多(RefreshListView)
查看>>
大数据开发实战:Hadoop数据仓库开发实战
查看>>