SpringIOC-注解

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
相关推荐
sg_knight19 分钟前
Spring 框架中的 SseEmitter 使用详解
java·spring boot·后端·spring·spring cloud·sse·sseemitter
郑州光合科技余经理2 小时前
同城系统海外版:一站式多语种O2O系统源码
java·开发语言·git·mysql·uni-app·go·phpstorm
一只乔哇噻3 小时前
java后端工程师+AI大模型开发进修ing(研一版‖day60)
java·开发语言·人工智能·学习·语言模型
LNN20223 小时前
Linuxfb+Qt 输入设备踩坑记:解决 “节点存在却无法读取“ 问题
开发语言·qt
Dolphin_Home3 小时前
笔记:SpringBoot静态类调用Bean的2种方案(小白友好版)
java·spring boot·笔记
foxsen_xia3 小时前
go(基础06)——结构体取代类
开发语言·算法·golang
MetaverseMan4 小时前
Java虚拟线程实战
java
巨人张4 小时前
C++火柴人跑酷
开发语言·c++
浪潮IT馆4 小时前
Tomcat运行war包的问题分析与解决步骤
java·tomcat
ID_180079054734 小时前
基于 Python 的 Cdiscount 商品详情 API 调用与 JSON 核心字段解析(含多规格 SKU 提取)
开发语言·python·json