• SSM框架学习——Spring之注解开发


    目录

    一、注解开发定义bean

    二、衍生注解

    三、纯注解开发

    3.1配置文件基础

    3.2Bean管理

    3.2.1单例控制演示

    3.2.2生命周期控制演示

    3.2.3Bean管理总结

    3.3依赖注入

    3.3.1使用@Autowired注解开启自动装配模式(按类型)

    3.3.2使用@Qualifier注解开启指定名称装配bean(依赖@Autowired)

    3.3.3使用@Value实现简单类型注入 

    3.3.4使用@PropertySource注解加载properties文件

    3.4第三方bean管理

    3.4.1使用@Bean配置第三方bean

    3.4.2使用独立的配置类管理第三方bean

    3.4.3实现为第三方bean注入资源

    总结


    一、注解开发定义bean

    ①使用@Component定义bean

    1. @Component("Service3")
    2. public class ServiceImpl3 implements Service3 {
    3. @Override
    4. public void show() {
    5. System.out.println("service3...");
    6. }
    7. }
    8. @Component
    9. public class ServiceImpl4 implements Service4 {
    10. @Override
    11. public void show() {
    12. System.out.println("service4...");
    13. }
    14. }

    ②核心配置文件中通过组件扫描加载bean

    <context:component-scan base-package="Service.impl"/>

    注意:如果@Component后面没有定义bean的id需要用类型来获取。

    1. ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    2. Service3 service3 = (Service3) context.getBean("Service3");
    3. service3.show();
    4. Service4 service4 = context.getBean(Service4.class);
    5. service4.show();

    二、衍生注解

    Spring提供@component注解的三个衍生注解:
    @Controller :用于表现层bean定义
    @Service : 用于业务层bean定义

    @Repository :用于数据层bean定义

    作用:只是为了区别不同层用的

    三、纯注解开发

    3.1配置文件基础

    Spring3.0升级了纯注解开发模式,使用]ava类替代配置文件,开启了Spring快速开发赛道。

    那么如何用Java类代替Spring核心配置文件?

    1. @Configuration //这个注解相当于原来配置文件中<?xml ?> <beans> </beans>这两个标签什么都不加。
    2. @ComponentScan({"Service.impl","Dao.impl"}) //这个注解相当于<beans> </beans>中的<context:component-scan/>
    3. public class SpringConfig {
    4. }

    如何运行?

    读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象。
     

    1. //加载配置文件初始化容器
    2. ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    3. //加载配置类初始化容器
    4. ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

    新的实现类AnnotationConfigApplicationContext。

    1. public class AppForAnnotation {
    2. public static void main(String[] args) {
    3. ApplicationContext context =new AnnotationConfigApplicationContext(SpringConfig.class);
    4. Service3 service3 = (Service3) context.getBean("Service3");
    5. service3.show();
    6. Service4 service4 = context.getBean(Service4.class);
    7. service4.show();
    8. Dao4 dao4 = context.getBean(Dao4.class);
    9. dao4.show();
    10. }
    11. }

    注意:

    @Configuration注解用于设定当前类为配置类.。
    @ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式。

    3.2Bean管理

    3.2.1单例控制演示

    ①编代码

    1. @Repository
    2. public class DaoImpl4 implements Dao4 {
    3. @Override
    4. public void show() {
    5. System.out.println("dao..");
    6. }
    7. }
    1. public class App10 {
    2. public static void main(String[] args) {
    3. ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    4. Dao4 dao1 =context.getBean(Dao4.class);
    5. Dao4 dao2 =context.getBean(Dao4.class);
    6. System.out.println(dao1);
    7. System.out.println(dao2);
    8. }
    9. }

    ②输出结果,可见是单例

     ③在DaoImpl4中新增注释@Scope("prototype")

    1. @Repository
    2. @Scope("prototype")
    3. public class DaoImpl4 implements Dao4 {
    4. @Override
    5. public void show() {
    6. System.out.println("dao..");
    7. }
    8. }

    ④再次运行输出结果,不一样有木有!

    3.2.2生命周期控制演示

    ①导入maven依赖坐标

    1. <dependency>
    2. <groupId>javax.annotation</groupId>
    3. <artifactId>javax.annotation-api</artifactId>
    4. <version>1.3.2</version>
    5. </dependency>

    ②添加注解

    1. @Repository
    2. @Scope("singleton")
    3. public class DaoImpl4 implements Dao4 {
    4. public void show() {
    5. System.out.println("dao..");
    6. }
    7. @PostConstruct //构造方法之后
    8. public void init() {
    9. System.out.println("init..");
    10. }
    11. @PreDestroy //销毁之前
    12. public void destroy() {
    13. System.out.println("destroy..");
    14. }
    15. }

    ③先不改上面的运行代码,运行发现没有执行销毁前方法

    ④如何修改?

    1. public class App10 {
    2. public static void main(String[] args) {
    3. //ApplicationContext没有close方法,改为AnnotationConfigApplicationContext
    4. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    5. Dao4 dao1 =context.getBean(Dao4.class);
    6. Dao4 dao2 =context.getBean(Dao4.class);
    7. System.out.println(dao1);
    8. System.out.println(dao2);
    9. context.close();
    10. }
    11. }

    ⑤再运行,成功执行destroy方法

    3.2.3Bean管理总结

    使用@Scope定义bean作用范围

    1. @Scope("singleton")//单例
    2. @Scope("prototype")//非单例

    使用@Postconstruct、 @PreDestroy定义bean生命周期

    1. @Postconstruct //构造之后执行
    2. @PreDestroy //销毁前执行

    3.3依赖注入

    3.3.1使用@Autowired注解开启自动装配模式(按类型)

    1. @Service
    2. public class ServiceImpl4 implements Service4 {
    3. @Autowired
    4. private Dao4 dao4;
    5. //@Autowired
    6. public void setDao4(Dao4 dao4) {
    7. this.dao4 = dao4;
    8. }
    9. @Override
    10. public void show() {
    11. System.out.println("service4...");
    12. dao4.show();
    13. }
    14. }

    @Autowired放在哪里都没有问题,

    1. @Service
    2. public class ServiceImpl4 implements Service4 {
    3. @Autowired
    4. private Dao4 dao4;
    5. @Override
    6. public void show() {
    7. System.out.println("service4...");
    8. dao4.show();
    9. }
    10. }

    注意︰自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法注意∶自动装配建议使用无参构造方法创建对象(默认),如果不提供对应构造方法﹐请提供唯一的构造方法。

    3.3.2使用@Qualifier注解开启指定名称装配bean(依赖@Autowired)

    1. @Repository("dao4") //指定id
    2. @Scope("singleton")
    3. public class DaoImpl4 implements Dao4 {
    4. public void show() {
    5. System.out.println("dao4..");
    6. }
    7. @PostConstruct //构造方法之后
    8. public void init() {
    9. System.out.println("init..");
    10. }
    11. @PreDestroy //销毁之前
    12. public void destroy() {
    13. System.out.println("destroy..");
    14. }
    15. }
    1. @Repository("dao41") //指定id
    2. public class DaoImpl5 implements Dao4 {
    3. @Override
    4. public void show() {
    5. System.out.println("dao41..");
    6. }
    7. }
    1. @Service
    2. public class ServiceImpl4 implements Service4 {
    3. @Autowired
    4. @Qualifier("dao41") //指定注入id为dao41的bean
    5. private Dao4 dao4;
    6. @Override
    7. public void show() {
    8. System.out.println("service4...");
    9. dao4.show();
    10. }
    11. }
    1. public class App11 {
    2. public static void main(String[] args) {
    3. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    4. Service4 service4 =context.getBean(Service4.class);
    5. service4.show();
    6. }
    7. }

    运行结果:

     从结果可以看出,指定注入的是dao41,但是dao4的init方法也被执行。

    注意:@Qualifier注解无法单独使用,必须配合@Autowired注解使用

    3.3.3使用@Value实现简单类型注入 

    1. @Repository("dao41")
    2. public class DaoImpl5 implements Dao4 {
    3. @Value("ylm")
    4. private String name;
    5. @Override
    6. public void show() {
    7. System.out.println("dao41.."+name);
    8. }
    9. }

    运行结果:

    3.3.4使用@PropertySource注解加载properties文件

    1. @Repository("dao41")
    2. public class DaoImpl5 implements Dao4 {
    3. @Value("ylm")
    4. private String name;
    5. @Value("${jdbc.password}")
    6. private String password;
    7. @Override
    8. public void show() {
    9. System.out.println("dao41.." + name + password);
    10. }
    11. }
    1. @Configuration
    2. @ComponentScan({"Service.impl","Dao.impl"})
    3. @PropertySource("jdbc.properties") //加载配置文件,多个配置文件依旧使用数组,但是不支持使用通配符
    4. //@PropertySource({"jdbc.properties","jdbc2.properties"})
    5. //@PropertySource({"classpath:jdbc.properties","classpath:jdbc2.properties"})
    6. //通配符是会报错的*.properties , classpath*:这两种都会报错。
    7. public class SpringConfig {
    8. }
    1. jdbc.driver=com.mysql.jdbc.Driver
    2. jdbc.url=jdbc:mysql://localhost:3306/brand
    3. jdbc.user=root
    4. jdbc.password=123456

    运行结果:

     注意∶路径仅支持单一文件配置,多文件请使用数组格式配置,不允许使用通配符*

    3.4第三方bean管理

    3.4.1使用@Bean配置第三方bean

    配置类

    1. @Configuration
    2. public class SpringConfig {
    3. //1.定义一个方法获得要管理的对象
    4. //2.添加@Bean,表示当前方法返回的是一个bean
    5. @Bean
    6. public DataSource dataSource(){
    7. DruidDataSource druidDataSource = new DruidDataSource();
    8. druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
    9. druidDataSource.setUrl("jdbc:mysql://localhost:3306/brand");
    10. druidDataSource.setUsername("root");
    11. druidDataSource.setPassword("123456");
    12. return druidDataSource;
    13. }
    14. }

    运行代码

    1. public class App12 {
    2. public static void main(String[] args) {
    3. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    4. DataSource dataSource = context.getBean(DataSource.class);
    5. System.out.println(dataSource);
    6. }
    7. }

    运行结果

    这样写有个问题,就是如果都这样写SpringConfig主配置类得写多少?接着看下面。

    3.4.2使用独立的配置类管理第三方bean

    方式一:扫描式

    这样改进,拆成专用配置类,放在包Config下,在主配置类SpringConfig里使用@ComponentScan注解扫描配置类所在的包,加载对应的配置类信息,都添加@Configuration。

    SpringConfig

    1. @Configuration
    2. @ComponentScan({"Config"})
    3. public class SpringConfig {
    4. }

    ThirdPartySpringConfig

    1. @Configuration
    2. public class ThirdPartySpringConfig {
    3. //1.定义一个方法获得要管理的对象
    4. //2.添加@Bean,表示当前方法返回的是一个bean
    5. @Bean
    6. public DataSource dataSource(){
    7. DruidDataSource druidDataSource = new DruidDataSource();
    8. druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
    9. druidDataSource.setUrl("jdbc:mysql://localhost:3306/brand");
    10. druidDataSource.setUsername("root");
    11. druidDataSource.setPassword("123456");
    12. return druidDataSource;
    13. }
    14. }

    再次运行App12:

    (其实我在测试ComponentScan时,不加ComponentScan,也不写@Configuration,依然能用,只要有个@Bean就可以,不知道为何,可能是为了更好的理解这样的思维方式)。

     这样还是不推荐,推荐使用的导入式,就是下面的方法。

    方式二:导入式

    推荐使用@Import,手动加入配置类到核心配置,此注解只能添加一次,多个数据请用数组格式

    SpringConfig

    1. @Configuration
    2. @Import({ThirdPartySpringConfig.class})
    3. public class SpringConfig {
    4. }

    ThirdPartySpringConfig

    1. //不用再写@Configuration
    2. public class ThirdPartySpringConfig {
    3. //1.定义一个方法获得要管理的对象
    4. //2.添加@Bean,表示当前方法返回的是一个bean
    5. @Bean
    6. public DataSource dataSource(){
    7. DruidDataSource druidDataSource = new DruidDataSource();
    8. druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
    9. druidDataSource.setUrl("jdbc:mysql://localhost:3306/brand");
    10. druidDataSource.setUsername("root");
    11. druidDataSource.setPassword("123456");
    12. return druidDataSource;
    13. }
    14. }

    运行结果:

    3.4.3实现为第三方bean注入资源

    依赖注入类型:

    简单类型注入(使用@Value),用成员变量。

    引用类型注入, 用方法形参。引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象

    ThirdPartySpringConfig 

    1. public class ThirdPartySpringConfig {
    2. //1.定义一个方法获得要管理的对象
    3. //2.添加@Bean,表示当前方法返回的是一个bean
    4. //简单类型
    5. @Value("com.mysql.jdbc.Driver")
    6. private String driver;
    7. @Value("jdbc:mysql://localhost:3306/brand")
    8. private String url;
    9. @Value("root")
    10. private String userName;
    11. @Value("123456")
    12. private String password;
    13. @Bean
    14. public DataSource dataSource(NewDao newDao){ //引用类型,NewDao按照类型自动装配
    15. System.out.println(newDao);
    16. DruidDataSource druidDataSource = new DruidDataSource();
    17. druidDataSource.setDriverClassName(driver);
    18. druidDataSource.setUrl(url);
    19. druidDataSource.setUsername(userName);
    20. druidDataSource.setPassword(password);
    21. return druidDataSource;
    22. }
    23. }

    NewDao

    1. @Repository
    2. public class NewDaoImpl implements NewDao {
    3. @Override
    4. public void show() {
    5. System.out.println("NewDao");
    6. }
    7. }

    运行代码

    1. public class App13 {
    2. public static void main(String[] args) {
    3. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    4. DataSource dataSource = context.getBean(DataSource.class);
    5. System.out.println(dataSource);
    6. }
    7. }

    运行结果:

    总结

    XML配置与注解配置比较:

    功能XML配置注解
    定义bean

    bean标签

       ·id属性

       ·class属性

    @Component

       ·@Controller

       ·@service

       ·@Repository

    @ComponentScan

    设置依赖注入

    setter注入( set方法)
       ·引用类型/简单类型

    构造器注入(构造方法)
       ·引用类型/简单类型

    自动装配

    @Autowired

       ·@Qualifier

    @Value

    配置第三方bean

    bean标签

    静态工厂、实例工厂、FactoryBean

    @Bean
    作用范围scope属性@Scope
    生命周期标准接口
       ·init-method
       ·destroy-method

    @PostConstructor

    @PreDestroy

    标红表示常用,可以重点学习复习。

  • 相关阅读:
    [Linux](8)进程地址空间
    通过tushare接口完成股票的实际交易的方法有哪些?
    RabbitMQ(七)延迟队列
    Android View体系
    【高质量C/C++】5.常量
    java家用电器远程管理系统
    线段树知识整理
    3、Shell变量
    【创建springboot-maven项目的pom.xml配置信息】
    基于HTML和JavaScript的会议室预约管理系统
  • 原文地址:https://blog.csdn.net/weixin_58035422/article/details/125469939