目录
面向切面编程(Aspect - Oriented Programming,AOP)
概要
在 Java 企业级开发的广袤领域中,Spring 框架宛如一颗璀璨的明星,以其强大而丰富的功能照亮了开发者前行的道路。其中,Spring IOC(Inversion of Control,控制反转)作为 Spring 框架的核心基石之一,更是为构建高效、可维护的应用程序提供了坚实的支撑。
Spring IOC 核心概念
控制反转(Inversion of Control)
在传统的 Java 编程世界里,对象之间的依赖关系犹如一张错综复杂的网,每个对象往往需要自行创建和管理其依赖的其他对象。如图:
public class UserService {
private UserDao userDao = new UserDao();
// 业务方法
public void doSomething() {
userDao.save();
}
}
这种方式虽然直观,但却带来了诸多弊端。其中最显著的问题便是代码的高度耦合,一旦Dao的实现类发生变化,Service类中的代码也必须随之修改,这无疑增加了系统维护的难度和风险。
Spring IOC 的出现,宛如一场及时雨,彻底改变了这一局面。它倡导将对象的创建和管理控制权从应用程序代码本身转移到外部的 Spring 容器中。简单来说,对象无需再自行操心其依赖对象的创建,而是由 Spring 容器统一负责。如图:
public class UserService {
private UserDao userDao;
// 通过构造器注入依赖
public UserService(UserDao userDao) {
this.userDao = userDao;
}
// 业务方法
public void doSomething() {
userDao.save();
}
}
此时,UserService类不再负责UserDao对象的创建,而是通过构造器参数接收由 Spring 容器注入的UserDao实例。
这样一来,UserService类与UserDao类的具体实现之间的耦合度被大大降低,系统的可维护性和扩展性得到了显著提升。当需要更换UserDao的实现类时,只需在 Spring 容器的配置文件中进行相应修改,而无需触动UserService类的代码。
面向切面编程(Aspect - Oriented Programming,AOP)
关于AOP我会在下面这篇博客里做详解
Spring 对 Bean 的管理
简介
在 Spring 的世界里,Bean 是构成应用程序的基本单元,它们是由 Spring IOC 容器负责创建、配置和管理的对象。Spring 对 Bean 的管理涵盖了从 Bean 的定义、创建、初始化,到其在运行时的依赖注入,再到最终的销毁等一系列生命周期的各个环节,宛如一位精心呵护孩子成长的家长,无微不至地照料着每一个 Bean。
Bean 的定义与注册
Spring 提供了多种灵活的方式来定义和注册 Bean,以满足不同开发者的需求和项目的特点。
基于 XML 配置文件的方式
在早期的 Spring 开发中,基于 XML 配置文件的方式是定义和注册 Bean 的主要手段,它具有直观、清晰的特点,即使对于初学者来说也易于理解和掌握。在 XML 配置文件中,我们使用<bean>标签来定义一个 Bean,通过id属性为 Bean 指定一个唯一的标识符,通过class属性指定 Bean 的实现类。如:
<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.xsd">
<bean id="demo" class="com.qcby.Demo"/>
</beans>
基于注解的方式
随着 Spring 的不断发展和演进,基于注解的方式逐渐崭露头角,成为了开发者们的新宠。它以其简洁、高效的特点,大大简化了 Bean 的定义和注册过程。
通过使用注解我们可以轻松地将一个类标记为 Spring 容器管理的 Bean。
其中:
- @Service:通常用于标记业务逻辑层的服务类
- @Repository:用于标记数据访问层的持久化类
- @Controller:用于标记 Web 层的控制器类
- @Component:是一个通用的组件注解,可以用于标记任何需要被 Spring 容器管理的类。
如:
@Service
public class Demo {
// 业务方法
}
基于不同配置方式的对象创建与属性注入
基于 XML 配置文件的方式
使用 get/set 方法的方式创建对象并注入属性
在基于 XML 配置文件使用 get/set 方法创建对象并注入属性时,首先需要在类中定义属性以及对应的 getter 和 setter 方法。如:
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
然后在 XML 配置文件中定义User Bean,并通过<property>标签注入属性值:
<bean id="user" class="com.example.domain.User">
<property name="name" value="张三"/>
<property name="age" value="25"/>
</bean>
在上述配置中,name属性指定了要注入的属性名称,value属性指定了要注入的值。Spring 容器在创建user Bean 时,会调用User类的setName和setAge方法,将相应的值注入到User对象的属性中。
使用构造器的方式创建对象并注入属性
使用构造器方式创建对象并注入属性时,需要在类中定义带有参数的构造器。假设User类修改为:
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
// 省略getter和setter方法
}
在 XML 配置文件中,可以通过<constructor - arg>标签来指定构造器参数的值:
<bean id="user" class="com.example.domain.User">
<constructor - arg value="李四"/>
<constructor - arg value="30"/>
</bean>
<constructor - arg>标签的顺序与构造器参数的顺序相对应,Spring 容器在创建user Bean 时,会调用User类的相应构造器,并将指定的值作为参数传递给构造器。
基于注解的方式
创建对象
基于注解创建对象非常简单,只需在类上使用相应的注解即可。如前文所述,使用@Component、@Service、@Repository、@Controller等注解都可以将一个类标记为 Spring 容器管理的 Bean。以@Service注解为例,对于UserService类:
@Service
public class UserService {
// 业务方法
}
Spring 容器在扫描组件时,会自动识别带有这些注解的类,并将其注册为 Bean。
注入属性
在基于注解注入属性时,Spring 提供了@Autowired、@Resource等注解。@Autowired注解是 Spring 自带的依赖注入注解,它可以用于字段、构造器、方法等位置,用于自动装配 Bean。例如,在UserService类中注入UserDao:
@Service
public class UserService {
@Autowired
private UserDao userDao;
// 业务方法
}
上述代码中,@Autowired注解会告诉 Spring 容器在容器中查找一个类型为UserDao的 Bean,并将其注入到userDao字段中。如果容器中存在多个类型为UserDao的 Bean,可以使用@Qualifier注解来指定具体要注入的 Bean。
@Resource注解是 JDK 提供的注解,它的功能与@Autowired类似,但在使用方式上略有不同。@Resource注解可以通过name属性指定要注入的 Bean 的名称,例如:
@Service
public class UserService {
@Resource(name = "userDaoImpl")
private UserDao userDao;
// 业务方法
}