SpringIOC-注解
一.注解
1.新建项目

2.配置自动导包

3 .Lombok生效问题
大部分电脑上,是idea自动配置完成的

4.引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.2.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.42</version>
</dependency>
5.创建配置类
//声明当前的类是配置类
@Configuration
public class SpringConfig {
// 把当前方法的返回值,添加到Spring容器中,交给Spring容器管理
//默认会把方法名当做bean的id
@Bean
public Student student1(){
return new Student(11,"小明");
}
}
6.实体类
public class Student {
public Integer id;
public String name;
public Student() {
System.out.println("----------========Student() =====----------");
}
public Student(Integer id, String name) {
this.id = id;
this.name = name;
}
public void t1(){
System.out.println("初始化方法");
}
public void t2(){
System.out.println("销毁方法");
}
}
7.测试类
public class Demo {
public static void main(String[] args) {
t1();
}
private static void t1() {
//创建Spring容器,读取配置类
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(SpringConfig.class);
//从容器中获取bean对象
Student student1 = applicationContext.getBean("student1", Student.class);
System.out.println(student1);
}
}
8 Spring启动原理
1 应用上下文初始化
通过new AnnotationConfigApplicationContext创建Spring容器
该构造函数会自动触发Spring的启动流程,包括:
扫描组件:基于SpringConfig配置类扫描注册的Bean
加载Bean定义:解析配置类中,Bean的定义信息
实例化Bean:根据Bean定义,创建Bean实例
2 配置驱动
使用AnnotationConfigApplicationContext基于注解配置驱动
传入SpringConfig.class 作为配置源,Spring会解析该配置类中的所有Bean定义
3 Bean的获取和使用
调用applicationContext.getBean("student1", Student.class);从spring容器中获取已经初始化的Bean
此时Spring已经完成所有单例Bean的创建和依赖注入
4 启动完成
当 AnnotationConfigApplicationContext构造完成的时候,Spring容器已经完全启动
所有配置的Bean都已经准备就绪,可以直接使用
整个过程,体现了Spring的控制反转,由框架负责Bean的生命周期管理
二.Bean的管理
1.获取Bean的方法
参考xml
2.创建Bean的方式
2.1构造方法
@Bean
public Student student1(){
return new Student(11,"小明");
}
2.2 静态工厂
@Configuration
public class SpringConfig {
//静态工厂
@Bean
public Student student2(){
return StudentStaticFactory.f1();
}
}
2.3 实例工厂
@Configuration
public class SpringConfig {
//实例工厂
//1 先将工厂本身 注册为Bean对象,
@Bean
public StudentFactory studentFactory(){
return new StudentFactory();
}
//2.调用工厂实例的方法创建目标Bean
@Bean
public Student student3(){
return studentFactory().f2();
}
}
2.4 Spring工厂
//Spring工厂
//声明当前bean的id是stu4
@Bean("stu4")
public StudentSpringFactory studentSpringFactory(){
return new StudentSpringFactory();
}
三 开启包扫描
1.修改配置类
@Configuration
//扫描查看 com.javasm包下,所有的类,看哪个类上面,加了Spring的注解
//如果加了注解,这个类就会被添加到Spring容器中
@ComponentScan("com.javasm")
public class SpringConfig2 {
}
2.创建新的实体类
@Data
//直接指明bean的id=abc
@Component("abc")
//相当于写了 id=user,类名首字母小写,当做bean的id
//@Component
public class User {
private Integer uid;
private String username;
}
3.延伸注解
| 注解 | 用途 |
|---|---|
| @Component | 通用注解,能把当前修饰的类,添加到Spring容器中 |
| @Controller | 用于web层,控制器,Controller层使用 |
| @Service | 用于业务逻辑层,Service使用 |
| @Repository | 用于数据访问层,Dao使用 |
四.其他注解
1.单例和懒加载
- 多例
@Scope("prototype")
@Scope(value = "prototype")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
- 懒加载
@Lazy
2.生命周期管理
@Configuration
@ComponentScan("com.javasm")
public class SpringConfig2 {
@Bean(name = "s1",initMethod = "t1",destroyMethod = "t2")
public Student stu1(){
return new Student();
}
}
- 直接写在类中
添加依赖
Spring6 全面迁移到了 Jakarta EE 9+规范,所有的API包名,从javax.* 改为了jakarta.* 因此 @PostConstruct也在jakarta.包下
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
@Setter
@Getter
@Component("abc")
public class User {
private Integer uid;
private String username;
public User() {
System.out.println("User构造方法");
}
@PostConstruct
public void f1(){
System.out.println("User 初始化");
}
@PreDestroy
public void f2(){
System.out.println("User 销毁");
}
}
五.依赖注入
1.直接赋值
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
public class GameModel {
@Value("123")
private Integer id;
@Value("英雄联盟")
private String name;
@Value("10.5")
private Double price;
//英雄列表
@Value("亚索,薇恩,盖伦")
private String[] heros;
//关卡
@Value("召唤师峡谷,咆哮森林,燃烧之地")
private List<String> levels;
//成就
@Value("无中生有,暗度陈仓")
private Set<String> achievements;
//配置
@Value("model=quanping,location=en")
private Properties gameConfig;
//下方三个 不能直接赋值
//背包
private Map<String,String> items;
//公司
private Company company;
//玩家列表
private List<Player> playerList;
}
2.按照类型注入(@Autowired)
@Autowired
根据bean的类型自动读取对象
如果想搭配id 精确的获取Bean对象
还需另外一个注解配合 @Qualifier
@Qualifier无法单独使用,比如搭配@Autowired
import org.springframework.beans.factory.annotation.Autowired;
- 修改配置类
@Configuration
@ComponentScan("com.javasm")
public class SpringConfig2 {
@Bean("qq")
public Company company(){
return new Company(1,"企鹅","深圳");
}
@Bean
public List<Player> gamePlayers(){
List<Player> playerList = new ArrayList<>();
playerList.add(new Player(1,"泉水指挥官"));
playerList.add(new Player(2,"闰土"));
return playerList;
}
@Bean
public Map<Integer,String > gameItems(){
Map<Integer,String > items = new HashMap<>();
items.put(1001,"霜之哀伤");
items.put(2001,"火之高兴");
return items;
}
}
- 修改GameModel
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
public class GameModel {
@Value("123")
private Integer id;
@Value("英雄联盟")
private String name;
@Value("10.5")
private Double price;
//英雄列表
@Value("亚索,薇恩,盖伦")
private String[] heros;
//关卡
@Value("召唤师峡谷,咆哮森林,燃烧之地")
private List<String> levels;
//成就
@Value("无中生有,暗度陈仓")
private Set<String> achievements;
//配置
@Value("model=quanping,location=en")
private Properties gameConfig;
//下方三个 不能直接赋值
//背包
@Autowired
@Qualifier("gameItems")
private Map<String,String> items;
//公司
//@Autowired 默认是根据类型匹配bean对象,优先寻找id=当前属性的bean
//只有根据id找不到Bean对象的时候,才会根据类型寻找
@Autowired
private Company qq;
//玩家列表
@Autowired
private List<Player> playerList;
}
3.按照名称注入(@Resource)
@Resource(name = "qq")
寻找id=qq的bean对象
@Resource
private Company qq;
寻找id=qq的bean对象
@Data
@NoArgsConstructor
@Component
public class Music {
private Integer id;
private String name;
private String time;
//@Resource(name = "qq")
@Resource
private Company cp;
}
3.读取配置文件
-
为了避免乱码,需要提前配置idea
-

-
新建配置文件:userconfig.properties
game.id=1001
game.name=王者荣耀
game.price=11.1
game.heros=妲己,鲁班,嫦娥
- 配置读取配置文件
@Configuration
@ComponentScan("com.javasm")
//加载 类的根路径下 userconfig.properties,指定编码 utf-8
@PropertySource(value = "classpath:userconfig.properties",encoding = "UTF-8")
public class SpringConfig3 {
}
- 实体类
@Data
@Component
public class Game2 {
@Value("${game.id}")
private Integer id;
@Value("${game.name}")
private String name;
@Value("${game.price}")
private Double price;
@Value("${game.heros}")
private String[] heros;
}
- 测试
六.实际应用

1.代码
- 实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class WebUser {
private Integer uid;
private String username;
}
- Dao
public interface WebUserDao {
WebUser selectById(Integer id);
}
@Repository
public class WebUserDaoImpl implements WebUserDao {
@Override
public WebUser selectById(Integer id) {
WebUser webUser = new WebUser();
webUser.setUid(id);
webUser.setUsername("admin");
return webUser;
}
}
- Service
public interface WebUserService {
WebUser findById(Integer id);
}
@Service
public class WebUserServiceImpl implements WebUserService {
@Autowired
WebUserDao webUserDao;
@Override
public WebUser findById(Integer id) {
return webUserDao.selectById(id);
}
}
- Controller
@Controller
public class WebUserController {
@Autowired
WebUserService webUserService;
public WebUser queryById(Integer id){
WebUser webUser = webUserService.findById(id);
return webUser;
}
}
- 测试类
public class WebUserApplication {
public static void main(String[] args) {
q1();
}
private static void q1() {
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(SpringConfig3.class);
WebUserController userController = applicationContext.getBean(WebUserController.class);
WebUser webUser = userController.queryById(999);
System.out.println(webUser);
}
}

七.总结
1 重点
-
必须会背的注解
@Component @Controller @Service @Resource @Autowired @Configuration @Bean -
熟练使用注解完成三层架构的调用
- Controller → Service → Dao
-
能详细描述@Resouce和@Autowired的区别
-
配置类的配置和启动
2.了解
@Scope
@Lazy
@PostConstruct
@PreDestroy
@Repository