文章目录
提示:以下是本篇文章正文内容,Java系列学习将会持续更新
一、存储Bean对象 (对象注册)
1. 配置扫描路径
想要将对象成功的存储到 Spring 中,我们需要配置一下存储对象的扫描包路径,只有被配置的包下的所有类,添加了注解才能被正确的识别并保存到 Spring 中。在spring-config.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/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描这个包的下所有类 -->
<context:component-scan base-package="com.spring.ioc" />
</beans>
注意:
如果我们创建的是SpringBoot项目,就不需要配置扫描路径。自带的启动类中的@SpringBootApplication
注解就可以有扫描包路径的功能。我们就不需要创建spring-config.xml文件。
// 扫描包路径
@SpringBootApplication
public class IocApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(IocApplication.class, args);
}
}
2. 添加注解存储Bean对象
想要将对象存储在 Spring 中,有两种注解类型可以实现:
- 类注解:
@Component
、@Controller
、@Service
、@Repository
、@Configuration
这些注解功能基本一致,只是使用场景不同。 - 方法注解:
@Bean
。
2.1 @Component (组件存储)
把普通pojo实例化到spring容器中,无特殊含义
// 可以和其它注解替换使用
@Component
public class User {
User(){
System.out.println("一个普通类");
}
}
2.2 @Controller (控制器存储)
控制层(controller)注入spring容器,处理http请求。
@Controller
public class SearchController {
@GetMapping("/web")
public String search(String query, @RequestParam(value = "page", required = false) String pageString, Model model) {
log.debug("查询: query = {}", query);
// 。。。。。。
}
}
2.3 @Service (服务存储)
业务逻辑层(server)注入spring容器,表示这个类里是具体的业务逻辑
@Service
public class UserService {
// UserService 对象依赖 UserDao 对象
private final UserDao userDao;
// 构造方法注入
@Autowired
public UserService(UserDao userDao) {
this.userDao = userDao;
}
// 注册用户
public User register(String username, String password) throws Exception {
// 。。。。。。
return user;
}
// 用户登录
public User login(String username, String password) throws Exception {
// 。。。。。。
return user;
}
}
2.4 @Repository (仓库存储)
持久层(dao)注入spring容器,表示这里是一个获取对象的类
@Repository
public class UserDao {
// 依赖 DataSource 对象才能完成,需要 Spring 帮我们注入 DataSource 对象
private final DataSource dataSource;
// 使用构造方法注入(依赖注入)
@Autowired
public UserDao(DataSource dataSource) {
this.dataSource = dataSource;
}
// 向数据库中插入新的用户
public void insert(User user) throws Exception {
try (Connection c = dataSource.getConnection()) {
String sql = "insert into users (username, password) values (?, ?)";
// 。。。。。。
}
}
}
// 从数据库中查找并返回用户
public User selectOneByUsername(String username) throws Exception {
try (Connection c = dataSource.getConnection()) {
String sql = "select uid, username, password from users where username = ?";
// 。。。。。。
}
}
return new User(...);
}
}
2.5 @Configuration (配置存储)
@Configuration作用于类上面,表明这是一个配置类,@Bean产生一个Bean对象加入Spring IOC容器
注意:@Configuration标注在类上,相当于把该类作为spring的xml配置文件中,作用为:配置spring容器(应用上下文)
注解 | 说明 |
---|---|
@Configuration | 作用于类上表示这是一个配置类,可理解为用spring的时候xml里面的< beans>标签 |
@Bean | 产生bean对象加入容器,作用于方法,可理解为用spring的时候xml里面的标签 |
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/java22_diaocha?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");
dataSource.setUser("root");
dataSource.setPassword("123456");
return dataSource;
}
}
2.6 @Bean (方法注解)
@Configuration
public class AppConfig {
@Bean
public String method() {
return "一个普通方法";
}
// 建议 @Configuration 和 @Bean 配套使用
// 相当于 <bean id="method" factory-bean="appConfig" factory-method="mehtod" />
}
二、获取Bean对象 (对象注入)
DI(依赖注入)的体现一个类的构造依赖于另一个类的存在。
类注入的3种方法:
- 构造方法注入
- Setter 注入
- 属性注入
方法注入的方法:@Bean
注入的前提: 我们要注入的对象的实例化过程已经被 Spring 管理,所以我们手动 new 一个对象的时候是不会发生注入的。
1. 类注入 @Autowired
@Autowired
是一种注解,可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作。
1.1 构造方法注入
// 前提是Hello类已经注册到Spring中了
@Component
public class Person {
// 1. 构造方法注入 [推荐]
@Autowired // 可以不写,建议写上(可读性)
public Person(Hello hello) {
// 如果没有 @Autowired,默认调用无参构造
System.out.println("Person的构造方法");
}
public Person() {
System.out.println("Person的无参构造");
}
}
1.2 setter方法注入
// 前提是Hello类已经注册到Spring中了
@Component
public class Person2 {
// 2. setter方法注入
@Autowired // 必须写
public void setHello(Hello hello) {
System.out.println("Person2的setHello()方法");
}
}
1.3 属性注入
// 前提是Hello类已经注册到Spring中了
@Component
public class Person3 {
// 3. 直接属性注入
@Autowired // 必须写
private Hello hello;
public void printHello() {
System.out.println(this.hello);
}
}
1.4 注入时的坑点
// setter/属性注入时会出现的坑点
@Component
public class 注入时的坑 {
@Autowired // 进行了属性注入
private Hello hello;
public 注入时的坑() {
System.out.println("Hello" + this.hello);
// 此时,hello的值还是为 null
// 因为构造方法的执行发生在 属性/setter注入 之前,相当于此时还没有注入
// 所以更推荐构造方法注入
}
}
2. 方法注入 @Autowired
方法参数注入:
@Configuration
public class Config {
@Bean
// 因为 createPerson() 被 spring 调用, 它可以填写我们指定的参数
public Person createPerson(@Autowired Hello hello) {
// 这里的 Hello hello 由 spring 注入,可以不用 @Autowired 注释
System.out.println("createPerson(), hello = " + hello);
// 这里创建的Person对象, 就不是 spring 传入的
return new Person(hello);
}
}
3. @Resource
注入的关键字也不只有@Autowired
关键字、还有关键字@Resource
,和@Autowired用法是差不多的,但是也有区别:
- 出身不同:@Autowired 来⾃于 Spring框架的注解,⽽ @Resource 是来⾃于 JDK 的注解;
- 用法不同:@Autowired 支持属性注入,构造方法注入,Setter注入,而@Resource是不支持构造方法注入的;
- 支持的参数不同:@Resource支持更多的参数设置,比如name、type设置,而@Autowired只支持required参数设置;
三、直接使用Bean对象
// 根据id获取Bean对象
Hello hello = (Hello) context.getBean("hello");
// 根据 类型 获取bean
Student student = context.getBean(Student.class);
// 根据 id + 类型 获取bean
Person person = context.getBean("person", Person.class);
// 调用对象的方法
person.createPerson(hello);
这就和之前的用法一样了。
总结:
提示:这里对文章进行总结:
以上就是今天的学习内容,本文是Spring的学习,学习了如何通过注解来管理Bean对象,认识了几种对象注册的注解和对象注入的注解。之后的学习内容将持续更新!!!