文章目录
- 1.Spring简述
- 1.1什么是Spring框架?
- 1.2Spring的核心功能
- 1.2.1 IOC
- (1)IOC介绍
- (2)控制?反转?
- 1.2.2 AOP
- (1)AOP介绍
- (2)专业术语
- (3)Spring AOP和AspectJ AOP有什么区别?
- (4)多个切面的执行顺序如何控制?
- 1.3Spring的架构
- 1.3.1Core容器
- 1.3.2数据访问/集成
- 1.3.3Web
- 1.3.4杂项
- 2.搭建Spring项目环境
- 2.1安装Spring框架库
- 2.2导入框架库
- 2.3创建类
- 2.4Bean配置文件
- 2.5运行程序
- 3.Spring Bean
- 3.1Bean定义
- 3.1.1元数据—>Bean标签的属性
- 3.1.2配置的方式
- (1)XML方式
- (2)注解方式
- 3.1.3@Component和@Bean的区别?
- (1)@Bean使用示例
- 3.2Bean作用域
- 3.2.1作用域分类
- 3.2.2配置作用域的方式
- (1)xml方式
- (2)注解方式
- 3.3Bean生命周期
- 3.3.1初始化回调
- (1)InitializingBean的afterPropertiesSet()方法
- (2)init-method属性指定初始化方法
- 3.3.2销毁回调
- (1)DisposableBean的destroy方法
- (2)**destroy-method**属性指定销毁方法
- 3.4Bean依赖注入
- 3.4.1定义
- 3.4.2依赖注入的作用
- 3.4.3依赖注入的方式
- (1)构造函数注入
- (2)Set方式注入(常用)
- (3)基于xml的自动装配
- ①搭建环境
- ②ByName自动装配
- ③ByType自动装配
- ④小结
- (4)基于注解的自动装配
- 3.4.4详讲@Autowired、@Qualifer、@Resource、@Value
- (1)@Autowired
- ①用在何处?
- ②三种情况
- (2)@Qualifer
- ①用在何处
- ②使用情况
- (3)@Resource
- (4)@Value
- (5)辨别@Autowired和@Resource的异同
1.Spring简述
1.1什么是Spring框架?
Spring 是一款开源的轻量级 Java 开发框架,旨在提高开发人员的开发效率以及系统的可维护性。
1.2Spring的核心功能
Spring提供的核心功能为 IOC控制反转(Inversion of Control)和 AOP面向切面编程 (Aspect-Oriented Programming)
1.2.1 IOC
(1)IOC介绍
- IoC(Inversion of Control:控制反转) 是一种设计思想,而不是一个具体的技术实现。
- IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。不过, IoC 并非 Spring 特有,在其他语言中也有应用。
(2)控制?反转?
- 控制:指的是对象创建(实例化、管理)的权力
- 反转:控制权交给外部环境(Spring 框架、IoC 容器)
将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。
在 Spring 中, IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个 Map(key,value),Map 中存放的是各种对象。
Spring 时代我们一般通过 XML 文件来配置 Bean,后来开发人员觉得 XML 文件来配置不太好,于是 SpringBoot 注解配置就慢慢开始流行起来。
1.2.2 AOP
(1)AOP介绍
- AOP(Aspect-Oriented Programming:面向切面编程):能够将那些与业务无关,却为业务模块所 共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
- Spring AOP 就是基于动态代理的
- 如果要代理的对象,实现了某个接口,那么 Spring AOP 会使用 JDK Proxy,去创建代理对象,
- 对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 Cglib 生成一个被代理对象的子类来作为代理,如下图所示:
(2)专业术语
术语 | 含义 |
---|---|
目标(Target) | 被通知的对象 |
代理(Proxy) | 向目标对象应用通知之后创建的代理对象 |
连接点(JoinPoint) | 目标对象的所属类中,定义的所有方法均为连接点 |
切入点(Pointcut) | 被切面拦截 / 增强的连接点(切入点一定是连接点,连接点不一定是切入点) |
通知(Advice) | 增强的逻辑 / 代码,也即拦截到目标对象的连接点之后要做的事情 |
切面(Aspect) | 切入点(Pointcut)+通知(Advice) |
Weaving(织入) | 将通知应用到目标对象,进而生成代理对象的过程动作 |
(3)Spring AOP和AspectJ AOP有什么区别?
-
Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。 Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)。
-
Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。
-
AspectJ 相比于 Spring AOP 功能更加强大,但是 Spring AOP 相对来说更简单,
-
如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比 Spring AOP 快很多
(4)多个切面的执行顺序如何控制?
- 通常使用 @Order 注解直接定义切面顺序
// 值越小优先级越高
@Order(3)
@Component
@Aspect
public class LoggingAspect implements Ordered {
}
- 实现
Ordered
接口重写getOrder
方法
@Component
@Aspect
public class LoggingAspect implements Ordered {
// ....
@Override
public int getOrder() {
// 返回值越小优先级越高
return 1;
}
}
1.3Spring的架构
Spring 框架提供了大约 20 个模块,可以根据应用程序需求使用它们。
1.3.1Core容器
Core 容器由 Core、Beans、Context 和 Expression Language 模块组成,详细信息如下 −
- Core 模块提供了框架的基本部分,包括 IoC 和依赖注入功能。
- Bean 模块提供了 BeanFactory,它是工厂模式的一个复杂的实现。
- Context 模块建立在 Core 和 Beans 模块提供的坚实基础之上,它是访问任何已定义和配置的对象的媒介。 ApplicationContext 接口是上下文模块的焦点。
- SpEL 模块提供了一种强大的表达式语言,用于在运行时查询和操作对象图。
1.3.2数据访问/集成
数据访问/集成层由 JDBC、ORM、OXM、JMS 和 Transaction 事务模块组成,详细信息如下 −
- JDBC 模块提供了一个 JDBC 抽象层,它消除了繁琐的 JDBC 相关编码的需要。
- ORM 模块为流行的对象关系映射 API 提供集成层,包括 JPA、JDO、Hibernate 和 iBatis。
- OXM 模块提供了一个抽象层,它支持 JAXB、Castor、XMLBeans、JiBX 和 XStream 的 Object/XML 映射实现。
- Java 消息传递服务 JMS 模块包含用于生成和使用消息的功能。
- Transaction 模块支持对实现特殊接口的类和所有 POJO 的编程和声明式事务管理。
1.3.3Web
Web 层由 Web、Web-MVC、Web-Socket 和 Web-Portlet 模块组成,具体如下 −
- Web 模块提供了基本的面向 Web 的集成功能,例如多部分文件上传功能以及使用 servlet 侦听器和面向 Web 的应用程序上下文初始化 IoC 容器。
- Web-MVC 模块包含 Spring 的 Web 应用程序的 Model-View-Controller(模型-视图-控制器) (MVC) 实现。
- Web-Socket 模块支持 Web 应用程序中客户端和服务器之间基于 WebSocket 的双向通信。
- Web-Portlet 模块提供了在portlet 环境中使用的MVC 实现,并反映了Web-Servlet 模块的功能
1.3.4杂项
其他重要的模块很少,如 AOP、Aspects、Instrumentation、Web 和 Test 模块,具体如下 −
- AOP 模块提供了一个面向方面的编程实现,允许您定义方法拦截器和切入点,以清晰地解耦实现应该分离的功能的代码。
- Aspects 模块提供与 AspectJ 的集成,AspectJ 又是一个强大且成熟的 AOP 框架。
- Instrumentation 模块提供类检测支持和类加载器实现以用于某些应用程序服务器。
- Messaging 模块支持将 STOMP 作为 WebSocket 子协议在应用程序中使用。 它还支持注解编程模型,用于路由和处理来自 WebSocket 客户端的 STOMP 消息。
- Test 模块支持使用 JUnit 或 TestNG 框架对 Spring 组件进行测试。
2.搭建Spring项目环境
2.1安装Spring框架库
下载路径: https://repo.spring.io/release/org/springframework/spring
下载完成之后,在libs 目录中可以找到所有 Spring 库
2.2导入框架库
IDEA导入Spring框架库
2.3创建类
- HelloWorld类
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
- MainApp类——主应用程序
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
}
}
- 第一步是在我们使用框架 API ClassPathXmlApplicationContext() 的地方创建应用程序上下文。 此 API 加载 bean 配置文件,并最终基于提供的 API,它负责创建和初始化所有对象,即配置文件中提到的 bean。
- 第二步用于使用创建的上下文的 getBean() 方法获取所需的 bean。 该方法使用 bean ID 返回一个通用对象,最终可以转换为实际对象。 一旦有了对象,就可以使用该对象调用任何类方法。
2.4Bean配置文件
-
该配置文件放置在src目录下即可
通常开发人员将此文件命名为 Beans.xml,必须确保该文件在 CLASSPATH 中可用,并在主应用程序中使用相同的名称
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
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-3.0.xsd">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
<property name = "message" value = "Hello World!"/>
</bean>
</beans>
2.5运行程序
运行MainApp程序,输出结果:
Your Message : Hello World!
3.Spring Bean
3.1Bean定义
简单来说,Bean 代指的就是那些被 IoC 容器所管理的对象。
我们需要告诉 IoC 容器帮助我们管理哪些对象,这个是通过配置元数据来定义的。配置元数据可以是 XML 文件、注解或者 Java 配置类。
3.1.1元数据—>Bean标签的属性
- 在IOC容器创建Bean对象时候,需要知道这三个信息
- 如何创建一个bean(class)
- bean的生命周期
- bean的依赖关系
所有配置元数据都转换为一组构成每个 bean 标签定义的以下属性:
序号 | 属性 | 描述 |
---|---|---|
1 | class | 指定了用于创建 bean 的 bean类型 |
2 | id或者name | 唯一地指定 bean 标识符 |
3 | scope | 指定从特定 bean 定义创建的对象的范围 |
4 | constructor-arg | 用于注入依赖关系 |
5 | properties | 用于注入依赖关系 |
6 | autowiring mode | 用于注入依赖关系 |
7 | lazy-initialization mode | 延迟初始化的 bean,即 告诉 IoC 容器在第一次被请求时创建一个 bean 实例,而不是在启动时 |
8 | initialization method | 在容器设置了 bean 上的所有必要属性之后调用的回调 |
9 | destruction method | 包含 bean 的容器被销毁时要使用的回调 |
3.1.2配置的方式
Spring IoC 容器与实际写入此配置元数据的格式完全分离。 以下是向 Spring 容器提供配置元数据的三个重要方法 −
- 基于 XML 的配置文件。(Spring)
- 基于注解的配置(SpringBoot)
- 基于 Java 的配置
(1)XML方式
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
<property name = "message" value = "Hello World!"/>
</bean>
(2)注解方式
@Component
:通用的注解,可标注任意类为Spring
组件。如果一个 Bean 不知道属于哪个层,可以使用@Component
注解标注。@Repository
: 对应持久层即 Dao 层,主要用于数据库相关操作。@Service
: 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。@Controller
: 对应 Spring MVC 控制层,主要用于接受用户请求并调用Service
层返回数据给前端页面。
3.1.3@Component和@Bean的区别?
-
相同:两者都是用来声明一个Bean类,交给IOC容器处理
-
不同:
- 作用的地方不同:@Component 注解作用于类,而==@Bean注解作用于方法==。
- 产生的作用不同:
@Component
通常是通过类路径扫描来自动侦测以及自动装配到 Spring 容器中(我们可以使用@ComponentScan
注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。@Bean
注解通常是我们在标有该注解的方法中定义产生这个 bean,@Bean
告诉了 Spring 这是某个类的实例,当我需要用它的时候还给我。
- 自定义强度不同:
@Bean
注解比@Component
注解的自定义性更强- 很多地方我们只能通过
@Bean
注解来注册 bean。比如当我们引用第三方库中的类需要装配到Spring
容器时,则只能通过@Bean
来实现
(1)@Bean使用示例
@Configuration
public class AppConfig {
@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
}
上面的代码相当于下面的 xml 配置:
<beans>
<bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>
3.2Bean作用域
3.2.1作用域分类
- singleton : IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。
- prototype : 每次获取都会创建一个新的 bean 实例。也就是说,连续
getBean()
两次,得到的是不同的 Bean 实例。 - request (仅 Web 应用可用): 每一次 HTTP 请求都会产生一个新的 bean(请求 bean),该 bean 仅在当前 HTTP request 内有效。
- session (仅 Web 应用可用) : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean(会话 bean),该 bean 仅在当前 HTTP session 内有效。
- application/global-session (仅 Web 应用可用):每个 Web 应用在启动时创建一个 Bean(应用 Bean),该 bean 仅在当前应用启动时间内有效。
- websocket (仅 Web 应用可用):每一次 WebSocket 会话产生一个新的 bean。
3.2.2配置作用域的方式
(1)xml方式
<bean id="..." class="..." scope="singleton"></bean>
(2)注解方式
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Person personPrototype() {
return new Person();
}
3.3Bean生命周期
对于普通的 Java 对象来说,它们的生命周期就是:
- 实例化
- 该对象不再被使用时通过垃圾回收机制进行回收
对于 Spring Bean 的生命周期来说:
- 实例化bean
- bean属性赋值
- 初始化bean
- 执行处理aware接口,分别调用 setBeanName()、setBeanFactory()、 setApplicationContext()方法
- 调用BeanPostProcessor的预初始化方法
- 调用InitializingBean的afterPropertiesSet()方法
- 调用init-method属性指定初始化方法
- 调用BeanPostProcessor的初始化后方法
- 使用bean
- 销毁bean
- 调用DisposableBean的destroy方法
- 调用destroy-method属性指定的方法
3.3.1初始化回调
(1)InitializingBean的afterPropertiesSet()方法
org.springframework.beans.factory.InitializingBean 接口指定单个方法
void afterPropertiesSet() throws Exception;
可以简单地实现上述接口,并且可以在 afterPropertiesSet() 方法中完成初始化工作,如下所示 −
public class ExampleBean implements InitializingBean {
public void afterPropertiesSet() {
// do some initialization work
}
}
public class ExampleBean implements InitializingBean {
public void afterPropertiesSet() {
// do some initialization work
}
}
(2)init-method属性指定初始化方法
基于 XML 的配置元数据的情况下,您可以使用 init-method 属性来指定具有 void 无参数签名的方法的名称。
<bean id = "exampleBean" class = "examples.ExampleBean" init-method = "init"/>
- 下面是类的定义
public class ExampleBean {
public void init() {
// do some initialization work
}
}
3.3.2销毁回调
(1)DisposableBean的destroy方法
org.springframework.beans.factory.DisposableBean 接口指定一个方法
void destroy() throws Exception;
因此,您可以简单地实现上述接口,并且可以在destroy() 方法中完成如下工作
public class ExampleBean implements DisposableBean {
public void destroy() {
// do some destruction work
}
}
(2)destroy-method属性指定销毁方法
- xml配置文件
<bean id = "exampleBean" class = "examples.ExampleBean" destroy-method = "destroy"/>
- 类的定义
public class ExampleBean {
public void destroy() {
// do some destruction work
}
}
3.4Bean依赖注入
3.4.1定义
- 依赖:bean对象的依赖于容器
- 注入:bean对象中的所有属性,由容器来注入
依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来。
3.4.2依赖注入的作用
-
作用:降低程序间的耦合
依赖关系的管理,以后都交给spring来维护
在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明依赖关系的维护,就称之为依赖注入。
3.4.3依赖注入的方式
-
可以注入的数据(三类):
- 基本类型和String
- 其他bean类型(在配置文件中或者注解配置过的bean)
- 复杂类型/集合类型:(不演示)
-
注入的方式(三种):十分重要
- 构造函数注入
- set方法注入
- 基于xml的自动装配(bean标签的autowire属性(byName—>根据bean标签的id属性查找、byType——>根据bean标签的Class属性查找))
- 注解注入()
(1)构造函数注入
-
定义:用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置的方式,让 spring 框架来为我们注入。
-
说明:
- 使用的标签:constructor-arg
- 标签出现的位置:bean标签的内部
- 标签中的属性:
- type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型。
- index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始。
- name:用于指定给构造函数中指定名称的参数赋值。
- ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
- value:要注入的数据
- 优点:在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
- 缺点:改变了bean对象的实例化方式,使得我们在创建对象时,如果用不到这些数据,也必须提供。
-
举例
<!--默认构造器方式--> <bean id="user" class="com.kuang.pojo.User"> <property name="name" value="张三"/> </bean> <!--通过有参构造创建对象。方式一:下标赋值--> <bean id="user" class="com.kuang.pojo.User"> <constructor-arg index="0" value="jerry"/> </bean> <!--通过有参构造创建对象。方式二:类型创建,不建议使用--> <bean id="user" class="com.kuang.pojo.User"> <constructor-arg type="java.lang.String" value="jarry"/> </bean> <!--通过有参构造创建对象。方式三:通过参数名,推荐使用--> <bean id="user" class="com.kuang.pojo.User"> <constructor-arg name="name" value="jarry"/> <constructor-arg name="birthday" ref="now"/> </bean> <!-- 配置一个日期对象 --> <bean id="now" class="java.util.Date"></bean>
(2)Set方式注入(常用)
- 定义:在类中提供需要注入成员的 set 方法
- 说明:
- 涉及的标签:property
- 出现的位置:bean标签的内部
- 标签的属性
- name:用于指定注入时注入的对象的名称(IOC容器会调用该对象的set方法)
- value:用于提供基本类型和String类型的数据
- ref:用于指定其他的bean类型数据。
- 优势:创建对象时没有明确的限制,可以直接使用默认构造函数。
- 弊端:如果有某个成员必须有值,则获取对象是有可能set方法没有执行。
(3)基于xml的自动装配
- 定义:
- 自动装配是spring满足bean依赖注解一种方式
- Spring会在上下文中自动寻找,并自动给bean装配属性
- 三种自动装配方式:
- 在xmI中显示的配置(ByName、ByType)
- 注解显示配置
- 隐式的自动装配bean 【重要】
①搭建环境
public class Cat {
public void shout(){
System.out.println("喵喵");
}
}
public class Dog {
public void shout(){
System.out.println("旺旺");
}
}
public class Person {
private Cat cat;
private Dog dog;
private String name;
@Override
public String toString() {
return "Person{" +
"cat=" + cat +
", dog=" + dog +
", name='" + name + '\'' +
'}';
}
//getting、setting
}
②ByName自动装配
- byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanId
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="person" class="com.kuang.pojo.Person" autowire="byName">
<property name="name" value="小海子"/>
</bean>
③ByType自动装配
- byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean
<bean class="com.kuang.pojo.Cat"/>
<bean class="com.kuang.pojo.Dog"/>
<bean id="person" class="com.kuang.pojo.Person" autowire="byType">
<property name="name" value="小海子"/>
</bean>
④小结
- byname的时候,需要保证所有bean的id唯一 ,并且这个bean需要和自动注入的属性的set方法的值一致。
- bytype的时候, 需要保证所有bean的class唯一 ,并且这个bean需要和自动注入的属性的类型一致;全局唯一,id属性可以省略。
(4)基于注解的自动装配
-
jdk1.5支持的注解,Spring2.5支持注解
-
作用:和在xml配置文件中的bean标签中写一个标签的作用是一样
-
注解:
注解 功能 使用前提 @Autowired 根据属性类型进行自动装配
即通过byType——>bean标签的class属性方式实现/ @Qualifer 根据属性名称(由@Component的value值指定)进行注入
即通过byName——>bean标签的id属性实现在该属性注入的基础上 @Resource 根据类型注入,可以根据名称注入(默认根据类型注入) / @Value 注入普通类型属性 /
3.4.4详讲@Autowired、@Qualifer、@Resource、@Value
- spring的IOC底层实际上就是一个Map结构容器,所谓**key 就是 bean标签 中的 id,value 则是对应 bean标签 中的 class**
(1)@Autowired
①用在何处?
- Spring 2.5 引入了 @Autowired 注释,可以对类成员变量、方法及构造函数、参数等进行标注【主要还是用在变量和方法上】,完成自动装配的工作。
- 使用@Autowired注解注入的属性,该属性不需要这个类提供set方法,方便快捷
- @Autowired作用就和在xml配置文件中的bean标签中写一个
< property >
标签的作用是一样的。 - @Autowired自动装配首先会在IOC容器中跳过key直接去容器中找到对应的属性(bean标签中的Class)!也就是说与key无关
②三种情况
- 容器中有==唯一的一个bean对象类型(Class类路径)==和被@Autowired修饰的变量类型匹配,就可以注入成功!
- 容器中没有一个bean对象类型和被@Autowired修饰的变量类型匹配,则注入失败运行报错。
- 容器中有==多个bean对象类型和被@Autowired修饰的变量类型匹配,则根据被@Autowired修饰的变量名寻找==,找到则注入成功【重点】
(2)@Qualifer
①用在何处
- @Qualifier的作用是在按照类中注入的基础之上再按照名称注入。
- 它在给类成员注入时不能单独使用(但是在给方法参数注入时可以单独使用)
- @Qualifier常常组合@Autowired一起使用,用来==指明具体名字的自动装配==
②使用情况
- UserDaoImpl2类
- UserService3类注入UserDaoImpl2类
(3)@Resource
-
@Resource由J2EE提供,默认是按照byName自动注入(通过名字自动注入),
-
@Resource有两个重要的属性,name和type
当然默认是通过name属性
type属性多此一举,还不如用@Autowired
-
@Resource 相当于 @Autowired + @Qualifier
举例:
@Autowired @Qualifier(value="userDaoImpl2") //相当于 @Resource(name="userDaoImpl2")
(4)@Value
- @Value专门用来注入基本类型和String类型数据
- @Value注解有一个value 属性:用于指定数据的值。它可以使用spring中SpEL(也就是spring的EL表达式)。SpEL的写法:${表达式},当然也可以类似mybatis中的 #{表达式} 的写法
@Value("#{2*3}") //#写法 表示6
private int age;
@Value("178") //普遍写法 178
private int height;
@Value("${man.weight}") //SpEL的写法一般操作配置文件中数据
private int weight;
(5)辨别@Autowired和@Resource的异同
- 相同:两者都是用来自动装配的,都可以放在属性字段上
- 不同:
- 实现方式不同:
- @ Autowired 通过byType的方式实现
- @Resource 默认通过byname的方式实现
- 找的过程不同:
- 若@ Autowired 通过byType的方式找不到,则报错
- 若@Resource 默认通过byname的方式找不到,则通过byType实现。如果两个都找不到的情况下,就报错。
- 实现方式不同: