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@Beanpublic 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构造方法
@Beanpublic Student student1(){return new Student(11,"小明");}2.2 静态工厂
@Configuration
public class SpringConfig {
//静态工厂@Beanpublic Student student2(){return StudentStaticFactory.f1();}
}2.3 实例工厂
@Configuration
public class SpringConfig {
//实例工厂//1 先将工厂本身 注册为Bean对象,@Beanpublic StudentFactory studentFactory(){return new StudentFactory();}//2.调用工厂实例的方法创建目标Bean@Beanpublic 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构造方法");}@PostConstructpublic void f1(){System.out.println("User 初始化");}@PreDestroypublic 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无法单独使用,比如搭配@Autowiredimport org.springframework.beans.factory.annotation.Autowired;
修改配置类
@Configuration
@ComponentScan("com.javasm")
public class SpringConfig2 {@Bean("qq")public Company company(){return new Company(1,"企鹅","深圳");}@Beanpublic List<Player> gamePlayers(){List<Player> playerList = new ArrayList<>();playerList.add(new Player(1,"泉水指挥官"));playerList.add(new Player(2,"闰土"));return playerList;}@Beanpublic 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对象的时候,才会根据类型寻找@Autowiredprivate Company qq;//玩家列表@Autowiredprivate List<Player> playerList;
}3.按照名称注入(@Resource)
@Resource(name = "qq") 寻找id=qq的bean对象@Resourceprivate Company qq;寻找id=qq的bean对象
@Data
@NoArgsConstructor
@Component
public class Music {private Integer id;private String name;private String time;//@Resource(name = "qq")@Resourceprivate Company cp;}3.读取配置文件
为了避免乱码,需要提前配置idea

新建配置文件:userconfig.properties
game.id=1001 game.name=王者荣耀 game.price=11.1game.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 {@Overridepublic 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 {@AutowiredWebUserDao webUserDao;@Overridepublic WebUser findById(Integer id) {return webUserDao.selectById(id);}
}Controller
@Controller
public class WebUserController {@AutowiredWebUserService 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
