文章目录
- spring概述
- Spring定义
- Spring核心
- Spring Framework的特点
- 基于注解管理bean
- 依赖
- 开启组件扫描
- 使用注解定义Bean
- 案例:
- @Autowired注入
- 属性注入
- set注入
- 形参上注入
- 只有一个构造函数,无注解
- @Autowire注解和@Qualifier注解联合
- @Resource注入
- Spring全注解开发
spring概述
Spring定义
- Spring是一款主流的Java EE 轻量级开源框架,目的是用于简化Java企业级引用的开发难度和开发周期。从简单性、可测试性和松耦合度的角度而言,任何Java应用都可以从Spring中受益。Spring框架提供自己提供功能外,还提供整合其他技术和框架的能力。
- Spring自诞生以来备受青睐,一直被广大开发人员作为Java企业级应用程序开发的首选。时至今日,Spring俨然成为了Java EE的代名词,成为了构建Java EE 应用的事实标准。
- 自2004年4月,Spring1.0 版正式发布以来,Spring已经步入到了第6个大版本,即 Spring6,本课程采用Spring5.3.24正式版本。Spring6版本支持JDK17
Spring核心
Spring指的是Spring Framework,通常我们称之为Spring框架。Spring框架是一个分层的面向切面的Java应用程序的一站式解决框架,它是Spring技术栈的核心和基础,是为了解决企业级引用开发的复杂性而创建的。
- Spring有两个核心模块:IoC和AOP。
- Ioc:Inverse of Control的简写,为 控制反转,指把创建对象交给Spring进行管理。
- OP:Aspect Oriented Programming 的简写,为 面向对象编程。AOP用来封装多个类的公共行为,将那些与业务无关,却为业务模块共同调用的逻辑封装起来,减少系统的重复代码,降低模块间的耦合度。另外,AOP还解决一些系统层面上的问题,比如日志、事务、权限等。
Spring Framework的特点
- 控制反转:IoC,反转资源获取方向;把自己创建的资源、向环境索取资源变为环境将资源准备好,我们享受资源注入。
- 面向切面编程:AOP,在不修改源代码的基础上增强代码功能。
- 容器:Spring IoC是一个容器,因为它包含并管理组件对象的生命周期;组件享受到了容器化的管理,替程序员屏蔽了组件创建过程中的大量细节,极大降低了使用门槛,大幅度提高了开发效率。
- 一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方库,而且在Spring旗下的项目已经覆盖了广泛领域,很多方面的功能性需求可以在Spring Framework 的基础上全部使用Spring来实现。
基于注解管理bean
- 从Java5开始,Java增加了对注解(Annotation)的支持,它是代码中的一种特殊标记,可以在编译、类加载和运行时被读取,执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下,在源代码中嵌入补充信息。
- Spring从2.5版本开始提供了对注解技术的全面支持,我们可以使用注解来实现自动装配,简化Spring的xml配置。
- Spring通过注解实现自动装配:
- 引入依赖
- 开启组件扫描
- 使用注解定义Bean
- 依赖注入
依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.24</version>
</dependency>
</dependencies>
开启组件扫描
- Spring默认不使用注解装配Bean,因此需要在Spring的xml配置中,通过context:component-scan元素开启Spring Beans的自动扫描功能。开启此功能后,Spring会自动从扫描指定的包(base-package属性设置)及其子包下的所有类,如果类上使用了@Component注解,就将该类装配到容器中。
- resources目录下创建spring配置文件 bean.xml
<?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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 2.开启组件扫描,让spring可以通过注解方式实现bean管理,包括创建对象、属性注入 -->
<!-- base-package:扫描哪个包中的注解,在com.text的包或者子包中建了类,在
类上、属性上、方法上加了spring的@Component注解,这里就能扫描到-->
<context:component-scan base-package="com.text.spring"></context:component-scan>
</beans>
使用注解定义Bean
Spring提供了以下多个注解,这些注解可以直接标注在java类上,将它们定义成Spring Bean。
注解 | 说明 |
---|---|
@Component | 该注解用于描述Spring中的Bean,它是一个泛化的概念,仅仅标识容器中的一个组件(Bean),并且可以作用在任何层次,例如Service层、Dao层等,使用时只需将该注解标注在相应的类上即可。 |
@Respository | 注解用于数据访问层(Dao层)的类标识为Spring中的Bean,功能与@Component相同。 |
@Service | 该注解通常作用在业务层(Service层),用于将业务层的类标识为Spring中的Bean,其功能与@Component相同。 |
@Controller | 该注解通常作用在控制层(如SpringMVC的Controller),用于将控制层的类标识为Spring中的Bean,其功能与@Component相同。 |
案例:
// value可以不写,默认为类名首字母小写
//@Component(value = "user") // <bean id="user" class="xxx">
//@Repository
//@Service
@Controller
public class User {
}
- 测试
public class TestUser {
@Test
public void testUser(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
User user = context.getBean("user", User.class);
System.out.println("user = " + user);
}
}
@Autowired注入
- 单独使用@Autowired注解,默认根据类型装配(byType)
- @Autowired注解有一个required属性,默认值是true,表示在注入的时候要求被注入的Bean必须存在,如果不存在则报错。如果required属性设置为false,表示注入的Bean存在或者不存在都没关系,存在就注入,不存在也不报错。
属性注入
- 控制器层controller.UserController
public class UserController {
private UserService userService;
public void addController(){
System.out.println("controller is running...");
userService.addService();
}
}
- 服务层service.UserService接口
public interface UserService {
public void addService();
}
- 服务层service.UserServiceImpl接口的实现类
public class UserServiceImpl implements UserService {
@Override
public void addService() {
System.out.println("service is running...");
}
}
- 在UserController和UserSerivceImpl中添加@Controller注解和@Service注解
- 在UserController中注入UserServiceImpl
@Controller
public class UserController {
// 注入service
// 第一种方式:属性注入
@Autowired // 根据类型找到对象,完成注入
private UserService userService;
}
- 测试类测试autowired.TestUserController
public class TestUserController {
@Test
public void testUserController(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
UserController controller = context.getBean(UserController.class);
controller.addController();
}
}
set注入
- 修改UserController类
// 第三种方式:构造方法注入
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
形参上注入
- 修改UserController类
// 第四种方式:形参注入
private UserService userService;
public UserController(@Autowired UserService userService) {
this.userService = userService;
}
只有一个构造函数,无注解
- 修改UserController类
// 第五种方式:只有一个有参数构造函数,无注解
private UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@Autowire注解和@Qualifier注解联合
- 再创建一个UserService接口的实现类service.UserServiceImpl2
@Service
public class UserServiceImpl2 implements UserService{
@Override
public void addService() {
System.out.println("service2 is running...");
}
}
-
测试发现报错
因为UserService有两个实现类,而@Autowired注解根据byType定位,所以找到了两个实现类
-
解决:修改UserController (使用两个注解)
// 1.第六种方式:根据类型和名称一起注入
@Autowired
@Qualifier(value = "userServiceImpl2") // 类名首字母小写
private UserService userService;
// 2.将构造函数注释
@Resource注入
@Resource注解也可以完成属性注入。它和@Autowired注解的区别如下
- @Resource注解是JDK扩展包中的,也就是说属于JDK的一部分。所以该解释是标准注解,更加具有通用性,而@Autowired注解是Spring框架自己的。
- @Resource注解默认根据名称装配byName,未指定name时,使用属性名作为name,通过name找不到的话会自动启动通过类型byType装配。而@Autowired注解默认根据类型装配byType,如果想根据名称匹配,需要配合@Qualifier注解一起使用。
- @Resource注解用在属性上、setter方法上
- @Autowired注解用在属性上、setter方法上、构造方法上、构造方法参数上。
案例 - 工程下创建包 resource,和之前一样,创建controller和service两个包,并创建UserController类和UserService接口以及该接口的实现类UserServiceImpl
- 修改UserController
@Controller("myUserController")
public class UserController {
// 根据名称进行注入
@Resource(name="myUserService")
private UserService userService;
public void add(){
System.out.println("controller...");
userService.add();
}
}
- 修改ServiceControllerImpl1
@Service("myUserService")
public class UserServiceImpl implements UserService {
- 指定@Resource中的name,则根据名称装配
- 未指定name时,则根据属性名装配
- 未指定name,属性名也不一致,则根据类型装配
Spring全注解开发
全注解开发就是不再使用spring配置文件了,写一个配置类来代替配置文件。
- 工程下创建包:config,创建类SpringConfig
// 配置类
@Configuration
// 开启组件扫描
@ComponentScan("cn.tedu.spring")
public class SpringConfig {
}
- 在resource下创建测试类进行测试
public class TestUserControllerAnno {
public static void main(String[] args) {
// 加载配置类
ApplicationContext context =
new AnnotationConfigApplicationContext(SpringConfig.class);
UserController controller = context.getBean(UserController.class);
controller.add();
}
}