Spring入门——IOC控制反转(DI依赖注入)
Spring有几点特性:
IOC控制反转,指原先在对象中要使用另一个对象就必须要显式的去创建另一个对象的实例。而Spring提供了IOC容器来帮我们生成所需要的对象,原先的对象中有用到其他对象的地方Spring会帮我们来注入。
DI依赖注入,在创建对象的过程中Spring可以依据配置对象的属性进行设置,这个过程称之为依赖注入。
基本pom.xml配置:

<dependencies> <!-- 核心容器(core container)--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.3.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.3.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.3.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.3.10</version> </dependency> <!-- AOP、aspects、spring-instrument 、messaging--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.3.10</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.9.7</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.7</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.10</version> </dependency> <!-- Data Access/Intergration--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.3.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>5.3.10</version> </dependency> <!-- web--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.3.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.10</version> </dependency> <!-- 日志相关jar包 (可选)--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>compile</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>compile</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>compile</scope> </dependency> </dependencies>
原方式:(举例)
1.dao层写入接口和Impl实体类:

public interface UserDao {
void findAllUsers();
}

public class UserDaoimpl implements UserDao {
public void findAllUsers() {
// sql:
System.out.println("查找到所有用户");
}
}
2.service层写入对应接口和Impl实体类:

public interface UserService {
// 查找所有用户
void getAllUsers();
}

public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoimpl();
public void getAllUsers() {
userDao.findAllUsers();
}
}
3.test类中声明serviceImpl实体类对象(+test引用方法):

@Test
public void testGetUsers(){
UserService userService=new UserServiceImpl();
userService.getAllUsers();
}
也就是需要在test类和service层的实体类中需要去显式地创建对象实例,分别是:
UserService userService=new UserServiceImpl();
private UserDao userDao = new UserDaoimpl();
进而有了【Spring提供了IOC容器来帮我们生成所需要的对象,原先的对象中有用到其他对象的地方Spring会帮我们来注入】
详细如下:
1.xml方式
scope:
1.singletion(默认),无论获取多少次,都是同一个对象。
2.prototype,每次获取重新实例化对象。
3.request,每次请求时新实例化对象。
4.session,每个会话对象内,对象是单例的(依赖于SpringMVC架构)。
如果是注解方式,则在需要的实体类上添加语句:
@Scope(value = "...")
1.1.1 需要在resource目录下的xml文件配置beans:

<bean id="userDao" class="com.swpu.dao.UserDaoimpl" scope="singleton" init-method="initUserDao"/> <bean id="userService" class="com.swpu.service.UserServiceImpl"> <property name="userDao" ref="userDao"></property> </bean>

public class UserServiceImpl implements UserService {
// private UserDao userDao = new UserDaoimpl();
@Autowired
private UserDao userDao;
//属性注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
//get注入不必要
public UserDao getUserDao() {
return userDao;
}
public void getAllUsers() {
userDao.findAllUsers();
}
}
1.2.1 配置引用方法

public void initUserDao() {
System.out.println("初始化userdao对象");
}
1.3.1 test——从容器中获取对象

public void testIOC() {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) ac.getBean("userService");
userService.getAllUsers();
}
1.1.2 (同上,换用构造注入)

<bean id="userDao" class="com.swpu.dao.UserDaoimpl" scope="singleton" init-method="initUserDao"/> <bean id="userService" class="com.swpu.service.UserServiceImpl"> <constructor-arg name="userDao" ref="userDao"></constructor-arg> </bean>

public class UserServiceImpl implements UserService {
// private UserDao userDao = new UserDaoimpl();
@Autowired
private UserDao userDao;
//构造注入
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
public void getAllUsers() {
userDao.findAllUsers();
}
}
1.2.2 配置引用方法与1.2.1相同
1.3.2 与1.3.1相同
2.注解方式
2.1 在resource目录文件下的xml文件中配置注解扫描:

<!-- 开启注册扫描--> <context:component-scan base-package="com.swpu"></context:component-scan>
2.2 在service层下实体类头部添加 @service,格式如下:

@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public void getAllUsers() {
userDao.findAllUsers();
}
}
2.3 在dao层下实体类头部添加 @Repository,格式如下:

@Repository
public class UserDaoImpl implements UserDao {
public void findAllUsers() {
// sql:
System.out.println("查找到所有用户");
}
// @PreDestroy 销毁方法头部添加
// @PostConstruct 初始化方法头部添加
public void initUserDao() {
System.out.println("初始化userdao对象");
}
}
2.4 test类——容器中获取对象:

@Test
public void testIOC() {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) ac.getBean("userServiceImpl");
userService.getAllUsers();
}
多类DI
选用xml方式注入:

<!-- 开启注册扫描--> <context:component-scan base-package="com.swpu.domain"></context:component-scan> <bean id="student1" class="com.swpu.domain.Student"> <property name="sid" value="1"></property> <property name="sname" value="刘亦菲"></property> </bean> <bean id="student2" class="com.swpu.domain.Student"> <property name="sid" value="2"></property> <property name="sname" value="黄渤"></property> </bean> <bean id="teacher" class="com.swpu.domain.Teacher"> <property name="tid" value="1"></property> <property name="tname" value="冯小刚"></property> </bean> <bean id="classes" class="com.swpu.domain.Classes"> <!-- 普通数据类型--> <property name="cid" value="1"></property> <property name="cname" value="表演1班"></property> <!-- 对象--> <property name="teacher" ref="teacher"></property> <!-- 数组--> <property name="sports"> <array> <value>足球</value> <value>篮球</value> </array> </property> <!-- list--> <property name="subjects"> <list> <value>语文</value> <value>数学</value> </list> </property> <!-- set--> <property name="students"> <set> <ref bean="student1"></ref> <ref bean="student2"></ref> </set> </property> <!-- map--> <property name="score"> <map> <entry key="语文" value="100"></entry> <entry key="数学" value="90"></entry> </map> </property> </bean>
注解式注入:
一般注入:

@Component(value = "user")
public class User {
@Value("1")
private String id;
@Value("张三")
private String name;
}
Autowired注入:(参考前文UserserviceImpl实体类注入UserDao属性)
【tips:Repository注解会将接口的实现类交给spring来管理,替换了UserDaoImpl类头上的"@Component(value = "userDao")" 语句,另外两个Service和Controller同理】
学习博客:
详细DI Autowired注解 Autowired注解注入规则实测
【Over】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!