学做美食网站,自定义网页,vs2010网站开发实例,网站开发支付功能上一篇并没有实际地带大家去看源码#xff0c;而是介绍了两个概念#xff1a;
BeanDefinitionBeanPostProcessor
当然#xff0c;我介绍得非常笼统#xff0c;不论是BeanDefinition还是BeanPostProcessor其实都有着较为复杂的继承体系#xff0c;种类也很多。作为Spring…上一篇并没有实际地带大家去看源码而是介绍了两个概念
BeanDefinitionBeanPostProcessor
当然我介绍得非常笼统不论是BeanDefinition还是BeanPostProcessor其实都有着较为复杂的继承体系种类也很多。作为Spring系列第一篇主要目的还是帮大家摆脱对Spring的刻板认知刷新你们的三观毕竟太多人对Spring的理解仅限于所谓的IOC和AOP。现在Spring5都出来了好多人还停留在Spring2.5、Spring3的年代还在使用XML。
今天我将会带大家复习Spring的基础大致流程是
复习XML方式开发通过逐步暴露XML的弊端引出Spring注解最终完全舍弃XML采用Spring注解开发
之所以推荐注解开发原因有两点
XML配置太繁琐了掌握Spring注解开发有助于后期学习SpringBoot
只有熟练使用Spring后看源码时才能把应用和原理联系起来。
文章篇幅较长建议看的时候先把下方目录截图放在一旁做引导防止自己看着看着不知道看到哪了。
主要内容
IOC与DISpring的3种编程风格与2种注入方式1️⃣XML配置开发bean描述依赖关系自动装配让bean职责单一化2️⃣XML注解XMLcontext:component-scanComponentAutowired的小秘密2️⃣JavaConfig注解ConfigurationComponentScanComponent3️⃣JavaConfig方式ConfigurationBean大乱斗ImportResource、Component、Bean IOC与DI
关于IOC的好处推荐一篇文章个人觉得写得很好Spring IoC有什么好处呢
大家不妨将IOC理解成一种思想而DI是实现该思想的一种具体方式。Spring被称为IOC容器它实现IOC的方式除了DIDependency Inject依赖注入其实还有DLDependency Look依赖查找。由于我们平时很少用到DL所以这里只讨论DI依赖注入。 IOC与DI
Spring依赖注入的做法
首先提供一些配置信息比如XML来描述类与类之间的关系然后由IOC容器Spring Context去解析这些配置信息继而维护好对象之间的关系。
!-- 配置信息在XML中定义Bean --
bean idperson classcom.bravo.annotation.Personproperty namecar refcar/property
/beanbean idcar classcom.bravo.annotation.Car/bean
其次还有一个很重要的前提是除了配置信息对象之间也要体现依赖关系。
public class Person {// Person类中声明了Car表示Person依赖Carprivate Car car;// 由于上面XML使用了property标签表示setter方法注入所以必须提供setter方法public void setCar(Car car) {this.car car;}
}
总结起来就是
编写配置信息描述类与类之间的关系XML/注解/Configuration配置类均可对象之间的依赖关系必须在类中定义好一般是把依赖的对象作为成员变量Spring会按照配置信息的指示通过构造方法或者setter方法完成依赖注入 XML中bean标签的职责1.定义bean 2.维护bean依赖关系指导Spring完成依赖注入 Spring的3种编程风格与2种注入方式
按照Spring官方文档的说法Spring的容器配置方式可以分为3种
Schema-based Container ConfigurationXML配置Annotation-based Container Configuration注解Java-based Container ConfigurationConfiguration配置类
Spring支持的2种注入方式
构造方法注入setter方法注入
在Spring4之前Spring还支持接口注入很少用这里不提及。
这个分类还是有问题后面分析源码时再解释
大家必须要明确所谓3种编程风格和2种注入方式到底指什么之间又有什么联系
我们从2种注入方式开始分析。
QSpring注入的是什么 A是Bean。 Q这些Bean怎么来的 AIOC容器里的。 所以所谓的3种编程风格其实指的是“将Bean交给Spring管理的3种方式”可以理解为IOC而2种注入方式即DI是建立在IOC的基础上的。也就是说Spring的DI依赖注入其实是以IOC容器为前提。 3种编程风格其实指的是3种把Bean交给Spring管理的方式而DI有2种方式setter方法注入/构造方法注入
接下来我们把3种编程风格分别用代码实验一下。
Spring系列文章我都会贴出完整、可运行的代码所以建议大家一边看一边复制到本地调试这样学得更快。 1️⃣XML配置开发bean描述依赖关系
setter方法注入
pom.xml dependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion4.3.12.RELEASE/version/dependency/dependencies
配置信息setter方法注入
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd!-- 在xml中描述类与类的配置信息 --bean idperson classcom.bravo.xml.Person!-- property标签表示让Spring通过setter方法注入--property namecar refcar/property/beanbean idcar classcom.bravo.xml.Car/bean/bean
Person这里偷懒把后面要讲的构造器注入的准备工作也做了对运行结果不影响
public class Person {// Person依赖Carprivate Car car;// 无参构造public Person(){}// 有参构造public Person(Car car){this.car car;System.out.println(通过构造方法注入...);}// setter方法public void setCar(Car car) {this.car car;System.out.println(通过setter方法注入...);}Overridepublic String toString() {return Person{ car car };
}
Car
public class Car {
}
Test
public class Test {public static void main(String[] args) {// 由于是XML配置方式对应的Spring容器是ClassPathXmlApplicationContext,传入配置文件告知Spring去哪读取配置信息ApplicationContext applicationContext new ClassPathXmlApplicationContext(spring-context.xml);// 从容器中获取PersonPerson person (Person) applicationContext.getBean(person);System.out.println(person);}
}
目录结构 测试结果 由于XML中配置依赖信息时使用了property标签所以Spring会调用setter方法注入
构造方法注入
接下来我们试一下构造方法注入
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd!-- 在xml中描述类与类的配置信息 --bean idperson classcom.bravo.xml.Person!-- constructor-arg标签表示让Spring通过构造方法注入--constructor-arg refcar/constructor-arg/beanbean idcar classcom.bravo.xml.Car/bean/beans
测试结果 其他代码都没变仅仅改变配置信息由property标签变为constructor-arg标签Spring就知道要改为构造器注入了 至此我们把XML配置下2种注入方式都实验过了它们的区别是
XML配置property 对象提供对应的setter方法XML配置constructor-arg 对象提供对应的构造方法
改变XML配置的同时需要对象提供对应的方法支持。如果你用了property却没有在类中提供setter方法则会报错。 自动装配让bean职责单一化
我们会发现bean这个标签其实承载着两个作用
定义bean告诉Spring哪个Bean需要交给它管理放入容器维护bean与bean之间的依赖关系
接下来我们思考这样一个问题
对于Person类
public class Person {// Person依赖Carprivate Car car;public void setCar(Car car) {this.car car;}
}
上面代码其实已经很好地描述了Person和Car的依赖关系此时在XML中继续用property或者constructor-arg反而成了累赘
既然类结构本身包含了依赖信息bean再用property等去描述就显得多余了如果类结构变动我们还需要额外维护bean的依赖信息很麻烦。比如Person新增了一个shoes字段那么bean又要写一个property表示shoes
所以最好的做法是把让bean标签职责单一化让它只负责定义bean把bean与bean的依赖关系转交给类自身维护有这个字段就说明有依赖。
既然菜鸡的我们能想到那么Spring肯定也想到了于是它提出了“自动装配”的概念。很多人一听到自动装配脑子里只有Autowired。不算错但其实XML也支持自动装配而且真要论先来后到的话肯定还是XML的自动装配在前。
XML实现自动装配可以分为两种全局、局部。
全局自动装配XML根标签beans末尾加default-autowire配置
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsddefault-autowirebyName!-- 在xml中只定义bean无需配置依赖关系 --bean idperson classcom.bravo.xml.Person/beanbean idcar classcom.bravo.xml.Car/bean/beans
所谓全局就是在XML根标签末尾再加一个配置default-autowirebyName那么在此XML中配置的每一个bean都遵守这个自动装配模式可选值有4个
byNamebyTypeconstructorno default其实就是no
测试结果 我们会发现改用自动装配后虽然没有了property标签但是默认是调用setter方法 局部自动装配每一个bean单独设置autowire
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd!-- 在xml中只定义bean无需配置依赖关系 --bean idperson classcom.bravo.xml.Person autowirebyName/beanbean idcar classcom.bravo.xml.Car/bean/bean
测试结果 小结
Spring支持自动装配全局/局部把原先bean标签的职责单一化只定义bean而依赖关系交给类本身维护自动装配共4种除了no其他3种各自对应两种注入方式byName/byType对应setter方法注入constructor对应构造方法注入 请自己动手证明 1、XML注解XMLcontext:component-scanComponent
原本bean标签有两个职责
定义bean描述依赖信息
上面通过自动装配把依赖信息交给类本身维护从此bean只负责bean定义。
现在我们想想办法能不能干脆把bean定义也剥离出来这样就不需要在XML中写任何bean标签了。我早就看bean标签不爽了这么一大坨要是bean多了就很臃肿。
怎么做呢
我们先来回顾一下手上的牌面 至此我们已经成功调教Spring帮我们做了自动装配也就是说IOC和DI中DI已经实现自动化。我们接下来要考虑的是如何减少IOC配置的工作量。
原先是把bean写在XML中再把XML喂给Spring
ApplicationContext applicationContext new ClassPathXmlApplicationContext(spring-context.xml);
既然现在打算消灭XML中的bean则说明即使把XML喂给Spring它也吃不到bean定义了。所以必须要告诉Spring去哪可以吃到bean。
我们来看一下当Spring吃下bean时到底吃了什么
!-- 在xml中只定义bean无需配置依赖关系 --
bean idperson classcom.bravo.xml.Person autowirebyName/bean
bean idcar classcom.bravo.xml.Car/bean
是的bean只指定了类名和自动装配的模式。也就是说要定义一个bean只需要最基本的两样东西
类名装配模式其实这个也不是必须的默认no不自动装配
而类名其实很好得到我们自己写的类不就有吗至于自动装配的模式也完全可以在类中通过注解指定。于是我们找到了改造的方向用带注解的类代替bean标签。 之前XML中写好bean标签后把XML喂给SpringSpring就会把bean实例化加到容器 现在消灭bean标签后XML中已经没有beanSpring必须自己去找bean定义
Spring2.5开始提供了一系列注解比如Component、Service等这些注解都是用来表示bean的。而Service等注解底层其实还是Component 之所以做一层封装是为了赋予它特殊的语义定义Service层的bean。其余的这里不再赘述。总之我们暂时理解为如果要使用注解表示bean定义我们能用的只有Component。 新建annotation包把Car和Person移过去 Person
Component //带注解的类我们希望用这种方式定义bean并让Spring把它吃进去
public class Person {// Person依赖Carprivate Car car;Overridepublic String toString() {return Person{ car car };}
}
Car
Component
public class Car {
}
XML什么都没有配置连自动装配模式也没指定因为不在这里定义bean了
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd/beans
Test不变
public class Test {public static void main(String[] args) {// 由于是XML配置方式对应的Spring容器是ClassPathXmlApplicationContext,传入配置文件告知Spring去哪读取配置信息ApplicationContext applicationContext new ClassPathXmlApplicationContext(spring-context.xml);// 从容器中获取PersonPerson person (Person) applicationContext.getBean(person);System.out.println(person);}
}
测试结果 在Spring容器中找不到person
其实很好理解我们传入了spring-context.xml告诉Spring去哪读取bean定义但是实际上XML却没有配置任何bean它是不可能把类实例化加入到容器的。
然而我们新定义的beanComponentSpring也没吃怎么回事
其实主要是因为我们的改变太突然了Spring以前吃惯了XML中的bean现在突然换成Component这种注解类它吃不惯甚至不知道它能吃
所以必须通知Spring
老哥我们改用注解了有Component注解的类就是bean和以前bean一样一样的。 如何通知只要在XML中配置 context:component-scan base-packagecom.bravo.annotation/
官方文档对这个标签的解释是
The use of context:component-scan implicitly enables the functionality of context:annotation-config. There is usually no need to include the context:annotation-config element when using context:component-scan. 翻译过来就是
使用context:component-scan隐式地启用了context:annotation-config的功能。context:annotation-config的作用是让Spring具备解析Component等注解的功能。当使用context:component-scan时通常不需要包含context:annotation-config元素。 这个标签的作用相当于什么呢Spring一口吃下去发现没有吃到bean却吃出了一张小纸条上面写着赶紧去找标了Component注解的类那是新菜式
所以最终/context:component-scan标签的作用有两个
扫描原先我们把写有bean定义的XML文件喂给Spring现在则让Spring自己去指定路径下扫描bean定义解析让Spring具备解析注解的功能
所以XML虽然不用配置bean标签却要配置扫描需要配置额外的名称空间
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsdcontext:component-scan base-packagecom.bravo.annotation//beans
测试结果 虽然能找到Person了但是Car并没有被注入
又出幺蛾子了怎么回事呢我们回想一下XML的bean定义
!-- 在xml中只定义bean无需配置依赖关系 --
bean idperson classcom.bravo.xml.Person autowirebyName/bean
bean idcar classcom.bravo.xml.Car/bean
我们设置了autowire属性告诉Spring按什么方式自动装配。
现在我们改用注解了Component只是相当于bean标签却没有指明自动装配的模式。如何在类中告诉Spring我们需要的装配方式呢
方法有很多种
AutowiredSpring提供的ResourceJSR-250定义InjectJSR-330定义
这里我们以Autowired为例
Component
public class Person {// 用Autowired告知Spring请把Car装配进来Autowiredprivate Car car;Overridepublic String toString() {return Person{ car car };}
}
测试结果 自动装配成功 Autowired的小秘密
上面我们有惊无险地从用Component替换了bean并且结识了Autowired这个超棒的注解用来完成自动装配。即
context:component-scanComponent彻底解放IOC配置Autowired完成自动装配
但是细心的小伙伴会发现相较于bean中的autowirebyNameAutowired虽然装配成功了却没有显式地指定自动装配的模式。
只有一种解释它有默认的装配方式。
在探究Autowire默认的装配模式之前关于bean的名称要和大家先交代一下
!-- 在xml中只定义bean无需配置依赖关系 --
bean idperson classcom.bravo.xml.Person autowirebyName/bean
bean idcar classcom.bravo.xml.Car/bean
在bean中id即为最终bean在Spring容器的名字。
同样的Component也提供了给bean命名的方法 Component(bravo)
public class Person {// 用Autowired告知Spring请把Car装配进来Autowiredprivate Car car;Overridepublic String toString() {return Person{ car car };}
}
如果不指定则默认会把类名首字母小写后作为beanName。
铺垫结束我们开始探究Autowired到底默认是哪种装配模式
byNamebyTypeconstructorno已经装配成功排除
先来看看是不是byName
Component
public class Person {// 用Autowired告知Spring请把Car装配进来Autowiredprivate Car myCar;Overridepublic String toString() {return Person{ car myCar };}
}
测试结果 Car在Spring中bean的名字应该是car而我把Person中的Car变量名改为myCar仍旧注入成功说明不是byName。
再来看看是不是byType。
这个稍微有点麻烦因为我需要弄出至少两个同类型的bean。所以我打算把Car变成接口然后创建Bmw和Benz两个实现类。这个接口只是为了试验没有实际意义
Car
//接口
public interface Car {
}//实现类Bmw
Component
public class Bmw implements Car {
}//实现类Benz
Component
public class Benz implements Car {
}
Person
Component
public class Person {// 用Autowired告知Spring请把Car装配进来Autowiredprivate Car car;Overridepublic String toString() {return Person{ car car };}
}
测试结果 熟悉的配方、熟悉的味道expected single matching bean but found 2: BMW,benz
很明显Autowired默认采用byType的方式注入由于当前Spring容器中存在两个Car类型的bean所以注入时报错了因为Spring无法替我们决定注入哪一个。
但是有个神奇的现象是你如果把变量名改为bmw或者benz就会注入对应的bean
Component
public class Person {// 把变量名改为bmwAutowiredprivate Car bmw;Overridepublic String toString() {return Person{ car bmw };}
} 也就是说Autowired默认采用byType模式自动装配如果找到多个同类型的会根据名字匹配。都不匹配则会报错。
当然有些人可能有强迫症觉得我Car类型的变量必须叫car但又想指定注入bmw怎么办我们先看看Autowired能不能指定名字吧 不能指定名字因为Autowired只有一个属性required表示当前bean是否必须被注入
为了弥补Autowired不能指定名字的缺憾Spring提供了Qualifier注解
Qualifier(benz)
Autowired
private Car car;
即使Spring容器中有两个Car类型的bean也只会按名字注入benz。 其他的我就不测了给个结论就好
Autowired默认byTypetype相同则byNameResource和Autowired几乎一样但不能配合Qualifier因为它本身就可以指定beanName。但没有required属性
Resource(name benz)
private Car car;
Inject用的很少不做讨论 2、JavaConfig注解ConfigurationComponentScanComponent
有没有发现上面标题还是2️⃣因为接下来要介绍的还是注解开发。
先复习一下前面两种方式
纯XMLbean负责定义beanJava类负责定义依赖Spring完成自动装配
!-- 在xml中只定义bean无需配置依赖关系 --
bean idperson classcom.bravo.xml.Person autowirebyName/bean
bean idcar classcom.bravo.xml.Car/bean 注解XMLComponentAutowired但我们发现注解并不能单独使用必须要XML中配置开启注解扫描才能生效 context:component-scan base-packagecom.bravo.annotation/ 之前我在注解上讲过注解的使用必须包含三步定义注解、使用注解、解析注解。Component是Spring定义、我们使用也肯定是由Spring解析。但是这个解析必须由我们手动开启。这就是context:component-scan标签的意义。
到了这一步我们已经把bean标签完全消灭了。但是这种模式有点不伦不类。
你说它叫XML配置开发吧它又有Component注解。你说它是注解开发吧XML中还有一个context:component-scan在那嘚瑟呢。所以如何才能完全消灭XML呢
究其根本我们发现无法消灭XML的原因在于注解的读取和解析必须依赖于context:component-scan标签因为我们要帮Spring开启注解扫描不然他不知道去哪读取bean。
既然bean标签可以被Component代替那么context:component-scan标签应该也能找到对应的注解。
不错这个注解就是ComponentScan如此一来我们就再也不需要spring-context.xml了。
但是转念一想脊背发凉...ClassPathXmlApplicationContext这个类要求我们必须传一个XML怎么办别担心Spring同样提供了一个注解Configuration目的是让我们可以把一个普通的Java类等同于一个XML文件而这个Java类就是JavaConfig我们习惯称之为配置类。
新建一个javaconfig包把annotation包下的所有类移过来并且新建AppConfig配置类
Configuration //表示这个Java类充当XML配置文件
ComponentScan(basePackages com.bravo.javaconfig) //相当于XML中的context:component-scan标签
public class AppConfig {}
这样我们就可以把XML删除用ComponentScan来开启注解扫描。
目录结构 准备测试时发现了大麻烦 ClassPathXmlApplicationContext无法接受AppConfig配置类它只认XML
所以用AppConfig配置类替代XML只是我们的一厢情愿吗
其实是我们选错了实现类。ApplicationContext的子类除了ClassPathXmlApplicationContext还有一个专门针对注解开发的AnnotationConfigApplicationContext。 新的Test
public class Test {public static void main(String[] args) {// AnnotationConfigApplicationContext是Spring用来专门针对注解开发的ApplicationContext子类ApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);// 从容器中获取PersonPerson person (Person) applicationContext.getBean(person);System.out.println(person);}
}
测试结果 稳得一批
至此XML已经被我们完全消灭了。 3、JavaConfig方式ConfigurationBean
严格来说上面的做法并不是所谓的Java-based Container ConfigurationConfiguration配置类风格。我们虽然用到了Configuration但只是为了让Java配置类替代XML最终消灭XML。这也太大材小用了...本质上这还是ComponentAutowired注解开发只是开启注解扫描的方式从context:component-scan标签变为ComponentScan。
实际上真正的Java-based Container Configuration编程风格是这样的
AppConfig如果你不扫描Component则不需要ComponentScan
Configuration
public class AppConfig {//new一个Benz对象通过Bean注解告知Spring把这个bean加到容器Beanpublic Car benz(){return new Benz();}//new一个Bmw对象通过Bean注解告知Spring把这个bean加到容器Beanpublic Car bmw(){return new Bmw();}//new一个Person对象通过Bean注解告知Spring把这个bean加到容器Beanpublic Person person(){Person p new Person();p.setCar(new Benz());return p;}}
Benz去除Component那是注解开发方式
public class Benz implements Car {
}
Bmw去除Component那是注解开发方式
public class Bmw implements Car {
}
Person去除Component那是注解开发方式
public class Person {private Car car;// setter方法。在Bean场景下手动调用setter方法设置成员变量public void setCar(Car car) {this.car car;}Overridepublic String toString() {return Person{ car car };}
}
测试结果 小结
Java-based Container Configuration编程风格指的是
用Configuration把一个普通Java类变成配置类充当XML在配置类中写多个方法加上Bean把返回值对象加到Spring容器中把配置类AppConfig喂给AnnotationConfigApplicationContext让它像解析XML一样解析配置类无需加Component注解因为我们可以手动new之后通过Bean加入容器 大乱斗ImportResource、Component、Bean
其实XML、注解、JavaConfig三种方式相互兼容并不冲突。
XML的beanComponent注解和扫描不论是context:component-scan还是ComponentScanConfiguration与Bean
为了证实它们确实不冲突我搞了很变态的一个项目里三种编程方式混用
两辆车子bmw和benz交给BeanJavaConfigPerson交给Component和ComponentScan注解Student交给XML和ImportResourceXML
目录结构 AppConfig
Configuration //JavaConfig方式把当前Java类作为配置类
ComponentScan(basePackages com.bravo.all)//注解方式开启扫描
ImportResource(spring-context.xml)//XML方式导入bean定义
public class AppConfig {Beanpublic Car benz(){return new Benz();}Beanpublic Car bmw(){return new Bmw();}}
Car
public interface Car {
}
BenzJavaConfig方式Bean加入Spring
public class Benz implements Car {
}
BmwJavaConfig方式Bean加入Spring
public class Bmw implements Car {
}
Person注解方式ComponentScan扫描Component加入Spring
Component
public class Person {// 用Autowired告知Spring请把Car装配进来Qualifier(benz)Autowiredprivate Car car;Overridepublic String toString() {return Person{ car car };}
}
StudentXML方式使用bean定义
public class Student {private Car bmw;//由于在下方XML配置中我选用了byName自动装配而byName/byType都要提供setter方法public void setBmw(Car bmw) {this.bmw bmw;}Overridepublic String toString() {return Student{ car bmw };}
}
spring-context.xml
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd!-- 在xml中描述类与类的配置信息 --bean idstudent classcom.bravo.all.Student autowirebyName/bean/beans
Test
public class Test {public static void main(String[] args) {// AnnotationConfigApplicationContext是Spring用来专门针对注解开发的ApplicationContext子类ApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);// 从容器中获取PersonPerson person (Person) applicationContext.getBean(person);System.out.println(person);// 从容器中获取StudentStudent student (Student) applicationContext.getBean(student);System.out.println(student);}
}
测试结果 通常来说我们日常开发一般是注解JavaConfig混用。也就是
ComponentScanConfigurationComponentBean 小结
纯XML配置开发没有注解全部bean标签但也可以配置自动装配注解开发不能单独存在需要开启扫描。自动装配一般用Autowired XML注解XMLcontext:component-scanComponentJavaConfig注解ConfigurationComponentScanComponentJavaConfig方式ConfigurationBean
通常我们都会两两混用比如XML注解或者JavaConfig注解但很少三种一起用。
本文目的是让大家知道
3种编程风格XML、注解、JavaConfig2种注入方式setter方法、构造方法4种装配模式byType、byName、constructor、no
然后有一点需要和大家说明本文关于所谓的2种注入方式和4种装配方式在宏观上来说是对的但是在源码层面上来说还是太笼统了。有机会的话后面专门写一篇自动装配相关的文章。