注:作者本人也是初学者,所以本文有些总结性见解可能存在问题,但是多数问题都是在上网查询过资料后总结的,如果有逻辑或者原理上的错误,或者见解不同,欢迎在评论区讨论!!!
目录:
2.3)第三种注入方式:p名称空间注入(set方法注入优化)
IOC
-
IOC底层原理
-
IOC接口(BeanFactory)
-
IOC操作Bean管理(基于xml)
-
IOC操作Bean管理(基于注释)
1.什么是IOC
(1)控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理
(2)使用IOC目的:为了耦合度降低
(3)做入门案例就是IOC的实现
1.1什么是控制反转
(1)控制反转并不是什么技术,而是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架(第三方)来管理。
(2)正控制:需要使用某个对象时,需要自己去负责对象的创建
(3)反控制:需要使用某个对象时,只需要从Spring容器中获取需要使用的对象,不关心对象的创建过程,将创建对象的控制权反转给Spring框架。
(4)那这样需要对象的时候就不需要面向其他对象,而是找IOC去要就行了,具体有没有不管我们事(这样就把开发的各个领域区分开来)。负责开发各个领域的人就不需要去找其他类获取对象,各个领域的职能被分割开了。
1.2什么是耦合性
耦合性(英语:Coupling,dependency,或称耦合力或耦合度)是一种软件度量,是指一程序中,模块及模块之间信息或参数依赖的程度。
内聚性是一个和耦合性相对的概念,一般而言低耦合性代表高内聚性,反之亦然。耦合性和内聚性都是由提出结构化设计概念的赖瑞·康斯坦丁所提出[1]。低耦合性是结构良好程序的特性,低耦合性程序的可读性及可维护性会比较好。
例子:两个类分别为学生类和计算器类,学生类中有计算方法,其方法体中创建了计算器类并调用了他的计算方法,这样学生类和计算机类中耦合度就太高了。当计算机类的位置改变时,学生类调用计算机类的位置也要跟着改变,当计算器类方法名发生改变时,学生类调用的计算器类方法名也要跟着改变。
1.2.1有关耦合性在开发中常见的问题
如果我们在开发中,负责后端的人员需要完成Service层的编写,而队友负责UserDao实现类的编写,我们在编写Service层实现类的时候不可避免的会调用UserDao类方法,因此就不可避免的需要创建对象,导入对象所在包。而如果UserDao相应的实现类还没有编写,我们负责Service层的人员无法创建对象,因此就无法继续向下编写,这样的代码结构耦合性极高。这里就诞生了IOC容器,Service把创建对象交给IOC容器,而UserDao把写好的对象配置给IOC,这样编写不同层代码的人就无需关注对方的进度,只需要关注自己的进度即可。
2.IOC底层原理
xml解析,工厂模式,反射(反射的目的:通过得到类的字节码文件,可以操作类中的所有内容)
2.1使用工厂模式解耦
在我们学习完javaweb我们都知道开发时所用到的三层架构,即负责处理请求信息的web层、处理业务的service层和处理数据的dao层。其中Service层需要调用dao层的一个或者多个数据处理方法,这样就不可避免的需要创建dao对象,导入dao包,那么在开发中如果负责编写dao层的人还没有完成代码,那么我们也就无法获取dao对象。
这时,我们就可以将创建对象的权利交给“别人”,也就是工厂类。
工厂类最开始无需把真正带有对象的返回值返回回去,只需要返回null(毕竟负责编写dao层的人还没有编写好,既然没有编写好,那么怎么用不存在的dao接口实现类创建对象?),那么编译器就不会报错,service层的人就拿到了dao对象(其实是null),调用接口中已经约束好功能的方法就可以完成service层的逻辑实现。当dao层的人写好代码开始整合的时候,我们再把Factory加工的类方法返回值全部改成实际返回值,这样一来大大加快了开发速度。
Service ——>Factory——>Dao
上述说法多少有些抽象,所以我们来举个生活中很常见的例子吧:
手机,我们日常中最常见的东西。一部手机有很多部分组成:
其中芯片的设计需要一个公司负责完成,比如华为海斯的麒麟芯片设计,美国高通的骁龙芯片设计,他们负责的是芯片设计职能,具体怎么做他们是不需要会的,他们只需要按照光刻机厂商提供的芯片制作规格去设计芯片即可。
而芯片的制作也无需考虑芯片如何设计,他们需要做的就是提高光刻机的精度,如何让光刻机可以制作7nm,5nm甚至4nm芯片,而这些芯片结构如何设计不管他们事。
芯片设计厂和芯片加工厂之间是各司其职,他们只需要在双方规定的协议之下做他们做的事即可,无需等你突破4nm制作工艺我再去设计4nm芯片,也无需等你会设计4nm芯片我再去突破4nm的制作工艺。这个协议就是负责两方交互的“Factory类”,他将两个本是一个职能的芯片服务分裂为多个,每个方面各司其职。
但是这样我们发现一个问题:虽然Service和Dao各司其职了,但是Factorty与Dao层的耦合性提高了,Factory需要根据Dao进行反复修改,于是就有了后面的IOC容器来进一步降低耦合性。
2.2使用IOC容器解耦
IOC容器解耦实际上是工厂类的再升级版本,因为他底层任然使用了工厂类进行相关操作
1.首先我们把需要创建类的路径都配置在一个文件中
2.在spring框架下,底层调用方法去读取配置文件中的每个地址,并利用Class进行对象的反射操作,创建对象,并将其安置在工厂类中
3.需要创建对象的时候,从IOC容器内部的工厂类去取即可
这样这个配置文件就成为了缓解耦合性的载体,编写程序的时我们也可以给配置文件直接留白,等到所有成员负责的领域都完工后,完善配置文件。
3.IOC(接口)
-
IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
-
Spring提供IOC容器实现两种方式:(两个接口)
1). BeanFactory:IOC容器基本实现方式,是Spring内部的使用接口,不提供开发人员进行使用 —— 加载配置文件时不会创建对象,在获取对象(使用)才去创建对象
2). ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用——加载配置文件时,就会把 你在配置文件中配置的对象 进行创建(可以结合tomcat使用,在服务器的init方法中,服务器启动时,就自动加载该配置文件)
ApplicationContext的两个后代实现类
-
FileSystemXmlApplicationContext类是通过盘符路径加载配置文件
-
ClassPathXmlApplicationContext类是通过类路径加载配置文件
IOC的几个体系
-
Resource体系:对资源的抽象,它的每一个实现类都代表了一种资源访问的策略。有了策略那就有加载资源的方法,Spring利用ResourceLoader来进行统一资源加载。
-
BeanFactory体系:BeanFactory是一个非常纯粹的bean容器,它是IOC必备的数据结构,其中BeanDefinition是他的基本结构,他内部维护着一个BeanDefinition map,并且可以根据BeanDefinition的描述进行bean的创建和管理。
-
BeanDefinition体系:BeanDefinition用来描述Spring中的Bean对象。
-
BeanDefinitionReader体系:BeanDefinitionReader的作用是读取Spring的配置文件的内容,并将其转换成ioc容器内部数据结构:BeanDefinition。
-
ApplicationContext体系:这也就是传说中的Spring容器,它叫做应用上下文,与我们应用息息相关,他继承BeanFactory,所以他是BeanFactory的拓展升级版:
-
继承MessageSource,提供国际化的标准访问策略
-
继承ApplicationEvenPublisher,提供强大的事件机制
-
扩展ResourceLoader,可以用来加载多个Resource,可以灵活访问不同的资源
-
对Web应用的支持。
-
IOC具体操作:Bean管理
1.什么是Bean管理
Bean管理指的是两个操作
-
Spring创建对象
-
Spring注入属性
2.Bean管理操作又两种方式
-
基于xml配置文件方式实现
-
基于注解方式实现
1)基于xml方式创建对象
-
在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
-
在bean标签有很多属性,介绍常用的属性
id属性:唯一标识
class属性:类全路径(包类路径)
-
创建对象时,默认也是使用对象的无参构造法(当不含无参构造法时会报错)
2)基于xml方式注入属性
-
DI:依赖注入,就是注入属性
-
注入时寻找参数:
-
name属性:通过构造参数名称找到对应参数
-
type属性:通过元素类型注入(同类型字段注入按照注入值顺序注入),type可以省略
-
index属性:通过参数下标找到对应参数
-
value属性:参数值--只包括基本数据类型和String类型
-
ref属性:在bean容器中查找id,将bean容器中的值注入到当前参数
-
2.1)第一种注入方式:使用set方法注入属性
-
设置类,设置属性以及set方法
public class Student { private String name; private int age; private long id; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setId(long id) { this.id = id; } public void show(){ System.out.println(name+" "+age+" "+ id); } }
-
在配置文件中bean标签内使用property标签进行设置(name和value)
<bean id="student" class="springStudyDay1.Student"> <property name="name" value="张三"></property> <property name="age" value="18"></property> <property name="id" value="2233"></property> </bean>
-
最后在测试类中通过IOC容器提供的ApplicationContext接口加载配置文件,获取加载器对象,最后通过getBean方法获取对象
public class Demo { @Test public void DemoStudent(){ //获取配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("springUserBean.xml"); //获取通过加载器对象获得学生对象 Student st = context.getBean("student",Student.class); //使用学生类中的show方法查看属性值是否改变 st.show(); } }
2.2)第二种注入方式:通过含参构造方法注入属性
-
创建类,定义属性,创建属性对应有参数构造方法
public class Book { private String name; private double price; public Book(String name, double price) { this.name = name; this.price = price; } public void show(){ System.out.println(name+" "+price); } }
-
在配置文件中进行文件配置这里在bean标签中使用constructor-arg标签
这里name的设置即可以根据属性名设置值,也可以根据他在构造器中的形参排序顺序设置值
<bean id="book" class="springStudyDay1.Book"> <constructor-arg name="name" value="三体"></constructor-arg> <constructor-arg name="price" value="49.5"></constructor-arg> </bean>
-
最终在测试类中测试代码运行结果
public class Demo02 { @Test public void TestBook(){ ApplicationContext context = new ClassPathXmlApplicationContext("springUserBean.xml"); Book book = context.getBean("book", Book.class); book.show(); } }
2.3)第三种注入方式:p名称空间注入(set方法注入优化)
-
第一步:修改xml文件配置(将第一行复制,键值后加:p,获取一个名称为p的命名空间,然后在后面的路径中把beans修改为p)
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="book3" class="com.ling.spring5.Book" p:name="明日方舟" p:author="海猫"></bean> </beans>
-
第二步:配置文件对象(使用bean标签创建对象,使用p:属性 = 值注入属性。)
-
注意:该方法只能对使用set注入的JavaBean对象生效,使用含参构造器的JavaBean对象无法使用
tips1:注入空值和特殊符号
-
在设置属性的时候不设置value值,而是在标签体内加上<null/>标签
<bean id="book4" class="com.ling.spring5.Book"> <property name="name" value="代码随想录"></property> <property name="author" > <null/> </property> </bean>
-
设置value值时有特殊符号,这时采用xml特有的CDATA语句
首先把value值单独拿到property内部作为一个标签 ,标签内写上<![CDATA[具体内容]]>,注意value内不要随意加回车,如果添加了,那么回车也会被当做值的一部分
<bean id="book5" class="com.ling.spring5.Book"> <property name="name"> <value><![CDATA[<代码随想录>]]></value> </property> <property name="author" value="Carl"></property> </bean>
注入属性-外部bean
注:之前的注入方法都是注入java已有类,例如String,而对于其他自定义的外部类注入方法我们还不曾知晓,所以此处讲解外部类的注入
-
创建两个类service类和dao类
-
在service类中调用dao里面的方法
-
在spring的配置文件中配置
<!--首先配置UserDao对象--> <bean id="userDao" class="com.ling.spring5.dao.impl.UserDaoImpl"></bean> <!--在有UserDao配置的基础上配置含有userDao作为属性的UserService--> <bean id="userService" class="com.ling.spring5.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"></property> <!--注意,这里ref取代了原本value的位置,其实是引用了对应的 配置对象id 获取配置对象--> </bean>
在外部注入中,两个bean是各自各家的两个JavaBean对象配置,只是后者通过id从外部引用了前者,这就是外部注入,外部可以理解为“非包含”。
注入属性-内部注入
-
和外部注入相似
-
不同点:主要用于处理一对多的关系,<bean>标签中配置属性<property>时就配置其他对象
<!--内部bean配置--> <bean id="userService2" class="com.ling.spring5.service.impl.UserServiceImpl"> <property name="userDao"> <bean id="userDao2" class="com.ling.spring5.dao.impl.UserDaoImpl"></bean> </property> </bean>
注入属性-级联赋值
其实就是在一个类A中如果有另外一个类a作为自己的属性,那么在配置本类A时,引入的类a就已经给自己的字段附上值,这就是级联赋值。
级联赋值方法
-
外部注入时,把将要引入的id对应的配置对象设置好字段值,然后在引入,这样在对象创建后,字段对象就已经被初始化,而非一个没设置值的对象。
<!--首先配置UserDao对象--> <!--此处以及配置好了userdao对象,如果有字段配置好字段,那么引用他的类就会获取配置化好的该类--> <bean id="userDao" class="com.ling.spring5.dao.impl.UserDaoImpl"></bean> <!--在有UserDao配置的基础上配置含有userDao作为属性的UserService--> <bean id="userService" class="com.ling.spring5.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"></property> <!--注意,这里ref取代了原本value的位置,其实是引用了对应的 配置对象id 获取配置对象--> </bean>
-
内部注入时,把<property>中新定义的<bean>配置文件字段对象赋好值,这样在对象创建后,对象的字段就已经被初始化,而非一个没设置值的对象。
<!--内部bean配置--> <bean id="userService2" class="com.ling.spring5.service.impl.UserServiceImpl"> <property name="userDao"> <!--此处配置对象,如果对象有字段则初始化字段,这样外部类就可以直接获取配置好的该类对象--> <bean id="userDao2" class="com.ling.spring5.dao.impl.UserDaoImpl"></bean> </property> </bean>
-
外部注入时,不初始化将要注入的内容,而是直接赋值
<!--不初始化内部字段对象--> <!--此处未设置部门内容--> <bean id="dept" class="com.ling.spring5.domain.Dept"></bean> <bean id="person" class="com.ling.spring5.domain.Person"> <property name="name" value="张三"></property> <!--引用未设置字段属性的dept--> <property name="dept" ref="dept"></property> <!--直接设置字段属性--> <property name="dept.name" value="人事管理部"></property> </bean>
注意:这里通过引用来的dept(第一行配置的id),需要直接设置字段,那么就需要拥有他的对象,所以这里需要在源文件中配置好他的get方法。
2.4)注入集合属性
-
数组配置:配置好对象后配置数组属性,value值用array标签包裹
<!--数组--> <property name="array"> <array> <value>张三</value> <value>李四</value> </array> </property>
-
list集合配置:配置好对象后配置list集合属性,value值用list标签包裹
<!--list集合--> <property name="list"> <list> <value>张三</value> <value>李四</value> </list> </property>
-
set集合配置:配置好对象后配置set集合属性,value值用set标签包裹
<!--set集合--> <property name="set"> <set> <value>张三</value> <value>李四</value> </set> </property>
-
map集合配置:配置好对象后配置map集合属性,与其他三个不一样,map集合改用entry标签,放在map标签内部,key和value值分别在内部赋值
<!--map集合配置--> <property name="map"> <map> <entry key="1号" value="张三"></entry> <entry key="2号" value="李四"></entry> <entry key="3号" value="王五"></entry> </map> </property>
- properties属性集配置:配置好对象后配置props属性,与其他四个集合不一样,properties标签改用props标签,在props标签内部依次使用prop标签进行键值对配置,key通过属性赋值,而value在标签之间赋值
<!--属性集配置--> <bean id="collection" class="com.ling.spring5.domain.Colloction"> <property name="properties"> <props> <prop key="name">张三</prop> <prop key="friend">李四</prop> <prop key="age">19</prop> </props> </property> </bean>
-
细节问题1:集合存储的是一个对象
其他的一切按照原list集合配置方式配置,但是当写到value标签时,改用ref标签,将外部的对象id写到ref标签的bean属性中。
<bean id="user1" class="com.ling.spring5.domain.User"> <property name="name" value="张三"></property> </bean> <bean id="user2" class="com.ling.spring5.domain.User"> <property name="name" value="李四"></property> </bean> <bean id="col" class="com.ling.spring5.domain.Colloction"> <property name="userList"> <list> <ref bean="user1"></ref> <ref bean="user2"></ref> </list> </property> </bean>
-
细节问题2:把集合注入部分提取出来,而不是普通的标签内置
1.首先配置xml引入的命名空间
<!--把第一行复制,后加“:util”,后面url后beans命名空间改用util命名空间--> <!--把最后一行复制,url中所有的beans改成util--> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
2.然后时配置list对象,整体思路和外部注入类似,首先定义两个user,留出id,定义list时导入id,然后定义对象,把list集合id导入对象属性中。这里糅合了“集合注入自定义的对象”和“外部注入”两个地方
<!--配置基础类对象--> <bean id="user1" class="com.ling.spring5.domain.User"> <property name="name" value="张三"></property> </bean> <bean id="user2" class="com.ling.spring5.domain.User"> <property name="name" value="李四"></property> </bean> <!--使用util命名空间,配置list对象,配置过程几乎和内部配置一样,注意留出id--> <util:list id="list1"> <ref bean="user1"></ref> <ref bean="user2"></ref> </util:list> <!--配置对象,配置方法和外部注入一样,在property中使用ref引入外部类--> <bean id="listXml" class="com.ling.spring5.domain.ListXml"> <property name="userList" ref="list1"></property> </bean>
2.5)自动装配
-
什么是自动装配
根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入
-
演示自动装配过程
第一种:根据属性名称自动注入
<!--首先配置属性值--> <bean id="dept" class="com.ling.spring5.domain.Dept"></bean> <!--根据名称自动配置,这里的名称就是类中属性的名称,当在xml中找到与属性名称相同的id时会自动配置属性--> <bean id="person1" class="com.ling.spring5.domain.Person" autowire="byName"></bean>
第二种:根据类型注入
<!--首先配置属性值--> <bean id="dept" class="com.ling.spring5.domain.Dept"></bean> <!--根据类型自动配置,这里的类型就是类中属性的类型,当在xml中找到与属性类型相同的配置对象时会自动配置属性--> <bean id="person2" class="com.ling.spring5.domain.Person" autowire="byType"></bean>
2.6)引入其他配置文件(分模块开发)
Spring的配置内容较多,体积较大,可以将Spring根据业务或者模块进行拆分,而在Spring的主配置文件(ApplicationContext对象中传入的文件)中通过import标签进行加载。
Bean补充1: FactoryBean
Spring有两种类型的bean,一种是普通bean,另外一种是工厂bean(FactoryBean)
-
普通bean:在配置文件中定义bean类型就是返回类型
以上学习的都是普通bean创建方式
-
工厂bean:在配置文件中定于bean类型可以和返回类型不一样
定义一个Java类,实现FactoryBean接口,重写三个方法,其中getObject方法用于确定该类真正的返回值:
public class MyBean implements FactoryBean { /** * 决定工厂bean返回值类型的方法 * 在使用xml配置文件进行配置时,通过getBean获取Mybean本类对象时,会调用getObject方法并将结果返回 * @return * @throws Exception */ @Override public User getObject() throws Exception { User user = new User(); user.setName("张三"); return user; } @Override public Class<?> getObjectType() { return null; } @Override public boolean isSingleton() { return false; } }
xml文件正常书写即可:
<bean id="myBean" class="com.ling.spring5.domain.MyBean"></bean>
Bean补充2: Bean作用域
-
在Spring里面,设置创建bean实例是单实例还是多实例
-
在Spring里面,默认情况下,bean是单实例对象,即返回的对象都是同一个对象(地址相同)
-
如何设置单实例还是多实例
-
在spring配置文件bean标签里面有属性(scope),用于设置单实例还是多实例
-
scope属性值
第一个值 默认值,singleton,表示是单实例对象
第二个值 prototype,表示是多实例对象,返回的对象地址也就不相同
-
-
singleton和prototype区别
-
singleton单实例,prototype多实例
-
scope设置为singleton时,加载spring配置文件时候就会创建单实例对象
scope设置为prototype时,不是在加载spring配置文件的时候创建对象,而是在调用getBean方法时创建多实例对象
-
Bean补充3: Bean的生命周期
什么是生命周期:从对象创建到对象销毁的过程
-
根据配置文件调用对象的无参构造器,创建对象
-
根据配置文件调用对象的set方法设置对象属性
-
执行后置处理器BeanPostProcessor接口中的postProcessBeforeInitialization前置初始化方法(会对所有配置文件实施)
-
执行自己配置的初始化方法,此处在xml需要配置init-method
-
执行后置处理器BeanPostProcessor接口中的postProcessAfterInitialization后置初始化方法(会对所有配置文件实施)
-
通过ApplicationContext对对象进行操作
-
通过ClassPathXmlApplicationContext的close方法关闭容器,执行自己配置的销毁方法,此处在xml需要配置destory-method
注:关于后置处理器
-
执行顺序:构造方法—>BeanPostProcessor的before—>init-method—>BeanPostProcessor的after。
-
实际运用中,可以配置多个BeanFactoryPostProcessor和BeanPostProcessor
-
应用场景
-
解析bean的注解,将注解中的字段转化为属性
-
统一将属性在执行前,注入bean中,如数据库访问的sqlMap,如严重服务,这样不需要每个bean都配置属性
-
打印日志,记录时间等。
-
3)使用注解进行配置
1. 获取类对象(在实现类上配置)
作用在类上,相当于xml配制中添加id,并将该对象放在Bean容器中
-
@Component:在类上用于实例化Bean
-
@Controller:使用在web层类上用于实例化Bean
-
@Service:使用在service层类上用于实例化Bean
-
@Repository:使用在dao层类上用于实例化Bean
步骤:
1.配置xml注解:使用注解开发,需要在核心配置文件中,指定那个包下的Bean需要进行扫描以识别使用注解配置的类和字段。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="org.example"></context:component-scan> </beans>
2.在实现类上使用注解
@Component("userDao") public class UserDaoImpl implements UserDao {}
3.加载配置文件,从IOC容器中获取对象
public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("anno.xml"); UserDao userDao = applicationContext.getBean("userDao", UserDao.class); System.out.println(userDao); }
2.在字段上注入属性
-
@Autowired使用在字段上用于根据类型依赖注入:相当于xml标签中的autowire属性,用于注入属性
-
使用多态的形式创建对象时,当该字段是自己写的类或接口,且该类的子类或者接口的实现类只有一个被注解过,那么系统就会直接查找到被注解的类,将其注入到其中
-
使用多态的形式创建对象时,当该字段是自己写的类或接口,且该类的子类或者接口的实现类有多个被注解,那么系统就会查找到所有该接口下被注解的类,根据属性名称比对注解设置的id,并将其注入到bean对象中
-
-
@Qualifier配置,结合@Autowired一起用于根据名称进行依赖注入,当遇到多个类注解且id与属性没有一个相同时,使用@Qualifier注解,来指定获取哪个类对象
-
@Resource,相当于@Autowired和@Qualifier结合,但是此处注解的value属性不等于name属性(name属性并不是最重要的属性),所以需要对name属性进行赋值:@Resource(name = "") ,按名称(id)进行依赖注入,相当于xml标签中的ref属性,用于注入属性
-
@Scope,作用在类上,标注Bean的作用范围,相当于xml中的scope属性(指定单例singleton还是多例prototype)
-
@PostConstruct:标注初始化方法,相当于xml中的init-method属性,用于定义初始化方法,在配置好对象之后执行
-
@PreDestory:标注销毁方法,相当于xml中的destroy-method属性,用于定义销毁方法,在ApplicationContext操作完对象后执行