1. 注解开发
上一节带大家了解了Spring的入门,是基于xml配置文件进行配置的,现在通过xml配置文件进行配置的方法已经淘汰了,现在用的比较多的是配置类进行配置。
1.1 导入坐标
java
<!-- 1.导入 spring-context 坐标 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.1.12</version>
</dependency>
</dependencies>
1.2 创建接口层、实现类、配置类以及测试类
UserDao
java
package com.it.dao;
public interface UserDao {
public void save();
}
UserDaoImpl,使用注解,将实现类交给Spring管理
java
package com.it.dao.impl;
import com.it.dao.UserDao;
import org.springframework.stereotype.Component;
// 2. 需要被Spring托管的bean,需要添加注解 Component
@Component
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("实现UserDao");
}
}
SpringConfig配置类,管理Bean对象
java
package com.it.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* 3. 配置类,用于定义Spring的配置信息。
* 使用@ComponentScan启用组件扫描,自动注册Bean。
*/
@Configuration // 标记为Spring的配置类
@ComponentScan("com.it") // 指定需要扫描的包路径
public class SpringConfig {
}
1.3 进行测试
java
package com.it;
import com.it.config.SpringConfig;
import com.it.dao.UserDao;
import com.it.dao.impl.UserDaoImpl;
import com.it.service.impl.UserServiceImpl;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
// 创建Spring IoC容器,并加载配置类SpringConfig
AnnotationConfigApplicationContext ioc =
new AnnotationConfigApplicationContext(SpringConfig.class);
// 从Spring IoC容器中获取UserDaoImpl的Bean实例
UserDaoImpl userDao = ioc.getBean(UserDaoImpl.class);
userDao.save();
}
}
再创建其他业务层道理是同样的,如果有一个service层,想要实现dao层的方法,该怎么实现呢?按照之前的逻辑需要在Service实现类中调用dao,如下
java
package com.it.service;
public interface UserService {
public void save2();
}
java
package com.it.service.impl;
import com.it.dao.UserDao;
import com.it.service.UserService;
import org.springframework.stereotype.Component;
@Component
public class UserServiceImpl implements UserService {
private UserDao userDao;
@Override
public void save2() {
System.out.println("实现UserService");
userDao.save();
}
}
java
package com.it;
import com.it.config.SpringConfig;
import com.it.dao.UserDao;
import com.it.dao.impl.UserDaoImpl;
import com.it.service.impl.UserServiceImpl;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
// 创建Spring IoC容器,并加载配置类SpringConfig
AnnotationConfigApplicationContext ioc =
new AnnotationConfigApplicationContext(SpringConfig.class);
// 从Spring IoC容器中获取UserDaoImpl的Bean实例
UserDaoImpl userDao = ioc.getBean(UserDaoImpl.class);
userDao.save();
UserServiceImpl userService = ioc.getBean(UserServiceImpl.class);
userService.save2();
}
}
但是这样会发现控制台会报一个空指针异常,是因为我们没有实例化对象

遇到事情不要慌~,只需要一个注解就可以完成实例化,即 @Autowired 注解

2. Bean配置
在注解开发中,bean配置的作用范围也是通过注解实现的,注解为@Scope,有两个比较常见的模式:
- 单例模式 singleton(默认)
- 非单例模式 prototype
2.1 单例模式 singleton
java
package com.it.dao.impl;
import com.it.dao.UserDao;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
// 2. 需要被Spring托管的bean,需要添加注解 Component
@Component
// @Scope("singleton") 表示该Bean在Spring容器中以单例模式存在,整个应用中共享一个实例,容器中只有一个对象
// @Scope("prototype") 表示每次请求该Bean时都会创建一个新的实例 每次用都会进行创建
@Scope("singleton")
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("实现UserDao");
}
}

2.2 非单例模式 prototype
java
package com.it.dao.impl;
import com.it.dao.UserDao;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
// 2. 需要被Spring托管的bean,需要添加注解 Component
@Component
// @Scope("singleton") 表示该Bean在Spring容器中以单例模式存在,整个应用中共享一个实例,容器中只有一个对象
// @Scope("prototype") 表示每次请求该Bean时都会创建一个新的实例 每次用都会进行创建
@Scope("prototype")
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("实现UserDao");
}
}
可以看到每创建一个对象,都是一个新的
3. Bean实例化
Bean对象的创建方式有三种:
- 构造方法方式(默认)
当该类被Spring容器实例化时会调用构造方法
java
package com.it.dao.impl;
import com.it.dao.UserDao;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
// 2. 需要被Spring托管的bean,需要添加注解 Component
@Component
// @Scope("singleton") 表示该Bean在Spring容器中以单例模式存在,整个应用中共享一个实例,容器中只有一个对象
// @Scope("prototype") 表示每次请求该Bean时都会创建一个新的实例 每次用都会进行创建
@Scope("prototype")
public class UserDaoImpl implements UserDao {
//
/**
* 构造方法,用于创建UserDaoImpl实例
* 当该类被Spring容器实例化时会调用此构造方法
*/
public UserDaoImpl() {
System.out.println("UserDaoImpl被创建了");
}
@Override
public void save() {
System.out.println("实现UserDao");
}
}
- 静态工厂方式(使用场景不多)
1. 创建实体类
java
package com.it.pojo;
public class Students {
private String name;
}
2. 实例化
java
package com.it.dao.impl;
import com.it.pojo.Students;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class StudentsDaoImpl {
/**
* 使用Spring的@Bean注解标识此方法将返回一个被Spring管理的Bean实例。
* 此方法是一个静态工厂方法,用于创建并返回一个Students实例。
* @return 一个新的Students对象实例
*/
@Bean
public static Students getStudents() {
System.out.println("静态工厂实例化");
return new Students();
}
}
3. 测试

- 实例工厂方式
实例工厂方式是用的最多的,常用来整合其他第三方技术
4. Bean生命周期
4.1 导入生命周期依赖坐标
java
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
4.2 Bean生命周期配置
- init-method:指定初始化方法名称
- destroy-method:指定销毁方法名称
5. Bean扫描注解
Spring框架中提供了详细扫描注解,规范开发,控制层有@Controller,业务层有@Service,持久层(实现类)有@Repository,将上面的案例代码修改如下
5.1 注解@Autowired作用
@Autowired 是一个注释,它可以对类成员变量、方法及构造函数进行标注,让 spring 完成 bean 自动装配的工作。
@Autowired 默认是按照类去匹配,配合 @Qualifier 指定按照名称去装配 bean