它是一个轻量级,非入侵式的控制反转(IoC)和面向切面(AOP)的容器框架.
Spring是一个生态:可以构建企业级应用程序所需的一切基础设施
通常Spring指的就是Spring Framework,它有两大核心:IOC和AOP
Spring的核心就是一个大的工厂容器,可以维护所有对象的创建和依赖关系,Spring工厂用于生成Bean,并管理Bean,实现高内聚低耦合的设计理念。
通俗的说,通过IOC的方式,如果在一个对象中使用另外的对象,从前我们需要手动地new对象,比如Connection还需要销毁,对象始终会和其他接口或类耦合,而使用IOC,对象的管理与创建都不用我们操心,也可以实现解耦的目的.
IOC 是一种编程思想,它通过控制反转的方式降低了代码之间的耦合度。在传统的程序设计中,我们通常会直接调用其他对象的方法。但在 IoC 框架中,控制权被反转,对象之间的调用由框架负责管理。这使得代码更易于测试和维护。IOC的目的是DI
DI即依赖注入,DI的前提是IOC,依赖注入的核心思想是将对象的依赖关系从硬编码中解耦出来,使得代码之间的耦合度降低。DI 可以通过构造器注入和Setter方法进行属性注入两种方式实现。
<?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.xsd">
<!--
bean标签:表示配置bean
id属性:表示给bean起名字
class属性:表示给bean定义类型
<bean id="" class=""></bean>
-->
<bean id="userDao" class="com.yaorange.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.yaorange.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
对应的java类
UserDao接口
public interface UserDao {
void getList();
}
UserDao实现类UserDaoImpl
public class UserDaoImpl implements UserDao {
@Override
public void getList() {
System.out.println("用户列表");
}
}
UserService接口以及实现类代码:
public interface UserService {
void selectUser();
}
public class UserServiceImpl implements UserService {
private UserDao userDao;
@Override
public void selectUser() {
System.out.println("执行service...");
userDao.getList();
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
通过IOC容器获取bean对象
public class Main {
public static void main(String[] args) {
//创建IOC容器
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
//从IOC容器中获取bean对象
UserService userService = ctx.getBean("userService", UserService.class);
userService.selectUser();
}
}
@Service
//开启事务管理
@Transactional(rollbackFor = Exception.class)
public class BookServiceImpl implements BookService {
@Autowired
private BooksMapper booksMapper;
@Override
public List<Books> selectAll() {
return booksMapper.selectAll();
}
}
@Configuration
//加载资源路径
@PropertySource("classpath:props/jdbc.properties")
public class JdbcConfig {
@Value("${jdbc.driverClass}")
private String driverClass;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.url}")
private String url;
/**配置Druid数据源*/
/**@Bean将返回的dataSource标识为被Spring管理的bean对象*/
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setUrl(url);
return dataSource;
}
}
提供bean的配置文件,容器通过BeanDefinitionReader读取配置文件或配置类
解析描述Bean的定义和依赖关系的配置文件,Bean定义包含了Bean的类名、作用域、构造函数参数、属性值等信息。根据解析的配置信息创建相应的BeanDefinition对象
IOC容器根据解析得到的BeanDefinition对象进行bean配置和初始化;在bean配置的过程中会进行依赖注入;在依赖注入的实现中,会使用反射来动态地创建对象实例
通过资源定位,配置文件解析,容器初始化以及依赖注入这些过程,IOC容器就完成了对象的创建/配置和依赖管理;
实现类:
BeanFactory的实现类:
ApplicationContext的实现类
通过类中属性的set方法实现属性赋值
代码示例:
public class UserService {
private UserRepository userRepository;
// 默认的构造函数
public UserService() {
}
// UserRepository的setter方法
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User getUserById(int id) {
return userRepository.findById(id);
}
}
public class UserRepositoryImpl implements UserRepository {
@Override
public User findById(int id) {
// 假设这里是从数据库中查找用户
return new User(id, "Username" + id);
}
}
在xml中通过<property>标签进行setter依赖注入
UserService
类有一个名为setUserRepository
的setter方法,它接受一个UserRepository
类型的参数。在Spring的XML配置文件中,<property>
元素用于指定要注入的属性名称(即setter方法的名称去掉set
前缀)和对应的bean引用。当Spring容器创建UserService
的bean时,它会调用setUserRepository
方法并将userRepository
?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">
<!-- 定义UserRepository的bean -->
<bean id="userRepository" class="com.example.UserRepositoryImpl"/>
<!-- 定义UserService的bean,并通过setter注入UserRepository -->
<bean id="userService" class="com.example.UserService">
<property name="userRepository" ref="userRepository"/>
</bean>
</beans>
通过类中构造函数实现属性赋值
?代码示例:
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User getUserById(int id) {
return userRepository.findById(id);
}
}
xml通过<constructor-arg >标签进行依赖注入
UserService类的依赖项UserRepository
通过XML配置进行了注入。通过使用<constructor-arg>
元素,将UserRepository
类型的bean引用传递给UserService
的构造函数。这样,当Spring容器创建UserService
的实例时,会自动将UserRepository
注入到构造函数中。
<!-- UserService的bean定义 -->
<bean id="userService" class="com.example.UserService">
<constructor-arg ref="userRepository"/>
</bean>
<!-- UserRepository的bean定义 -->
<bean id="userRepository" class="com.example.UserRepository"/>
自动装配是Spring框架中的一种机制,用于自动将依赖项注入到应用程序对象中。通过自动装配,开发人员可以专注于应用程序的业务逻辑,而不需要手动创建和管理依赖关系。
除了基于XML的配置方式,自动装配还可以通过注解的方式实现。例如,可以使用@Autowired注解来自动注入依赖项。
@AutoWired与@Qualifier的说明
在使用@Autowired注解时,需要注意以下几点:
- @Autowired默认按照类型进行匹配,如果存在多个相同类型的bean实例,会产生歧义。
- 如果需要指定特定的bean实例,可以使用@Qualifier注解。
- @Autowired可以标注在类成员变量、方法及构造函数上,用于标注依赖关系。
- 对于setter注入和构造器注入,可以使用@Autowired注解。
- @Autowired注解会自动创建实体,并自动调用方法中的参数。
@Qualifier,用于解决@Autowired注入时的歧义问题。当Spring容器中有多个相同类型的Bean时,如果没有使用@Qualifier,则Spring会抛出异常,因为无法确定应该注入哪个Bean。使用@Qualifier可以消除这种歧义,让Spring明确注入指定的Bean。
@Qualifier要与@AutoWired一起使用