Spring--DI依赖注入详解
目录
目录
前提:
一.DI介绍
二.依赖注入方式
2.1构造函数注入
2.2Setter方法注入
2.3属性注入
三.超简便的获取类
五大类注解
方法注解
@Autowired和@Resource
前提:
学习该知识点前,我们应该了解什么是IOC(Inversion of Control,控制反转) http://t.csdnimg.cn/ptEBR
一.DI介绍
依赖注入(Dependency Injection,简称DI)是指通过外部容器在对象之间建立依赖关系的一种方式。换一句话:就是由 IoC 容器在运⾏期间,动态地将某种依赖关系注⼊到对象之中。
与控制反转是同一个概念,或者:依赖注入是实现控制反转的一种常见方式。
目的:处理对象之间的依赖关系
依赖注入的三种形式:1.构造方法注入、2.setter注入、3.基于注解的注入
废话不多说,纯文字,谁看得懂啊!!!接下来展示一波代码
对了如果使用该方法获取类:
注意点:bean的命名是大驼峰时,获取应该使用小驼峰。如果bean不是大驼峰,获取时,使用全名!
#
二.依赖注入方式
在讲解注入方式之前,我们先学习一下@Autowired
@Autowired注解时,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:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
</beans>
假设我们有一个User类, 类中有一个变量名为username:
public class User{
private String username;
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
'}';
}
}
2.1构造函数注入
利用前提的User类,通过构造方法注入值,因此我可以在Spring的配置文件中配置
User类添加一个构造方法:
public User(String username) {
this.username = username;
}
xml添加的配置:
<bean id="user" class="org.sang.User">
<constructor-arg name="username" value="张三"/>
</bean>
如此我们就配置完成了
测试方法:
@Test
public void test4() {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
System.out.println(user);
}
结果:
构造注入的优点:
- 可以注入final变量
- 注入的对象不会该改变,因为构造方法只能加载一次
- 构造方法可以保证注入对象完全初始化
2.2Setter方法注入
set方法注入是我们用的比较多的一种注入方式,这种注入方式也很简单,但是不能有构造方法,不然会分不清楚是构造还是set方法注入。
User类添加一个Set方法:
public void setUsername(String username) {
this.username = username;
}
xml配置:
<bean id="user" class="com.example.reknowspring01.User">
//该类的username命名为李四
<property name="username" value="lisi"/>
</bean>
测试方法和之前一样,结果:
构造方法的缺点:
- 无法注入一个final变量
- setter注入的对象可以被修改,毕竟setter本身就是一个方法,因此可能会被多次调用
2.3属性注入
属性注入需要使用四种注解 : @Controller、@Bean()、@Autowired、@Qualifier(“”)
User类修改:
@Controller
public class User{
private String username;
@Bean("user1")
public User User1() {
User user=new User();
return user;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
'}';
}
}
需要使用讲类注入到Controller当中,但同样不需要在xml当中标明bean对象的来源,因为已经存在了Spring当中,且获取时,可以直接使用。
测试类:
@Autowired
@Qualifier("user1")
private User user1;
@Test
public void test4() {
user1.setUsername("属性注入");
System.out.println(user1);
}
注: @Autowired、@Qualifier(“”)得搭配使用,
@Qualifier(“”)当中的属性名必须等于@Bean的属性名
缺点:
- 麻烦,需要使用4个注解
- 无法注入final修饰的变量。
#
三.超简便的获取类
在第二部分里,我们可以发现无论是哪种方式获取类对象,都十分麻烦。要么需要在xml当中配置文件,要么需要使用4个注解!因此我更加推崇以下的获取类方法!但是我们需要先了解一下,Spring常用注解。
五大类注解
- @Controller:用于标记控制器类,通常作为 Spring MVC 中的控制器组件。Spring 会自动检测使用了
@Controller
注解的类,并将其注册为 Spring 应用上下文中的 bean。 - @Service:用于标记服务类,表示该类用于处理业务逻辑。通常在服务层的类中使用
@Service
注解,Spring 会自动扫描并将其注册为 bean,同时还会处理事务等相关功能。 - @Repository:通常用于标记数据访问层(DAO)的类,表示该类用于数据库操作。使用
@Repository
注解可以让 Spring 自动扫描并注册 DAO 类,同时还能转换持久层异常为 Spring 的数据访问异常。 - @Component:是一个泛化的概念,表示任何被 Spring 管理的组件,可用于标记任意类。其他三个注解(@Controller、@Service、@Repository)都是
@Component
的派生注解。 - @Configuration:用于标记配置类,通常与
@Bean
注解一起使用,提供应用程序上下文的 Bean 配置信息。@Configuration
注解的类可以包含一个或多个@Bean
方法,用于定义 Spring 容器中的 bean。
方法注解
@Bean注解:需要配合五大类注解使用。通过在方法上使用 @Bean
注解,可以告诉Spring容器该方法将返回一个Bean实例,该实例将被注册到Spring应用程序上下文中,以便在需要的地方进行使用。
@Autowired和@Resource
@Autowired是一个Spring框架中的注解,用于自动装配(Autowiring)Bean。通过
@Autowired
注解,Spring会自动在容器中查找匹配某个类型的Bean,并将其注入到需要的地方。可省略在XML配置文件中显式指定依赖关系的步骤,使得代码更加简洁和易于维护。@Resource 是Java EE(Java Platform, Enterprise Edition)提供的注解之一,用于实现依赖注入。在Spring框架中,也可以使用
@Resource
注解来标记需要注入的Bean,类似于@Autowired
注解的作用。
使用以上两个注解,xml配置文件将不再使用复杂的方式配置,只需要加一段代码即可!
注:使用@Autowired或@Resource ,也是需要搭配五大类注解
二者之间的区别:
代码整合:
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:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
//自动扫描com包以下的使用注解的类,并注入到Spring当中
<content:component-scan base-package="com.java"></content:component-scan>
</beans>
该配置会自动扫描com包下java包的bean对象。
假设Service 类如下:
import org.springframework.stereotype.Service;
//将此类注入到Spring当中
@Service
public class UserService {
/**
* 根据 ID 获取⽤户数据
*
* @param id
* @return
*/
public User getUser(Integer id) {
// 伪代码,不连接数据库
User user = new User();
user.setId(id);
user.setName("Java-" + id);
return user;
}
}
Controller类如下:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
// 注⼊⽅法1:属性注⼊
@Autowired //或者@Resource(name = "userservice")
private UserService userService;
public User getUser(Integer id) {
return userService.getUser(id);
}
}
我们可以知道,通过@Autowired的自动装配功能,我们可以直接使用UserService类,也可以使用@Resource(name = “userService”)装配
还没有评论,来说两句吧...