Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇)

2年前 (2022) 程序员胖胖胖虎阿
255 0 0

文章目录

  • 💨更多相关知识👇
    • 一、依赖注入
      • 🍂@Autowired注解
      • ⚡扩展@PostConstruct的使用(@Autowired,构造方法,@PostConstruct的执行顺序)⚡
        • ⚡扩展问题演示与解决
        • ⭐@Autowired注解演示
      • 🍂 @Qualifier注解
        • ⭐@Qualifier注解演示
      • 🍂 @Value注解
        • ⭐@Value注解演示
    • 二、PropertySource注解加载properties文件
      • ⭐代码演示
    • 三、第三方资源配置管理
      • 🍁使用 @Bean注解 配置第三方资源bean
        • ⭐代码演示
      • 🍁 将独立的配置类加入核心配置
        • ⭐导入式代码演示
        • ⭐扫描式代码演示
      • 🍁 简单类型与引用类型依赖注入
        • ⭐代码演示
    • 四、XML配置 和 注解配置的 区别
  • 作者:KJ.JK

💨更多相关知识👇

💖Spring中的创建对象的三种方式、第三方资源配置管理详细描述及使用(XML版完结篇)

💖Spring中的bean的配置、作用范围、生命周期详细描述及使用(XML版上篇)

💖Spring中的依赖注入、setter与构造器注入、自动装配与集合注入详细描述及使用(XML版中篇)

💖异常处理与解决方案详解上篇

💖异常处理与解决方案详解下篇

💖Math类与System类的常用方法使用

💖JavaEE中的静态方法定义、方法重载要求、return作用详解

💖List接口的常用方法,精华总结

💖JavaEE中的Stream流的常用方法

💖JavaEE中的Stream流知识点使用,精华总结,一文直接上手


🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈
 
🍂个人博客首页: KJ.JK
 
欢迎大家点赞👍收藏💖评论💬关注🔒
 
💖源码获取 | 💻学习交流 | 🤝商务合作 | 💨私信作者
 
💨推荐一款实用的模拟面试、刷题练习算法的神器、适用于所有的程序猿👉点击开始免费刷题,跟着博主走上巅峰💪


一、依赖注入


🍂@Autowired注解

               * 使用 "@Autowired注解"开启"自动装配模式"  (默认按类型注入,如果有多个类型相同的按名称)
                   
               * @Autowired(required = false): 找不到就算了(会报错)
                   
               * 直接加在成员变量上使用
                   
                   @Service
                   public class BookServiceImpl implements BookService {
                       
                      @Autowired
                      private BookDao bookDao;
                       
                       
                      public void setBookDao(BookDao bookDao) {      //set方法可以省略
                          this.bookDao = bookDao;
                      }
                       
                       public void save() {
                           System.out.println("book service save ...");
                           bookDao.save();
                       }
                   }

               
               
/*

 注意:
 
  自动装配基于反射设计创建对象并"暴力反射"对应属性为私有属性初始化数据,因此"无需提供setter方法"
  
  自动装配建议使用无参构造方法创建对象(默认)

   执行顺序:
   
          构造方法执行 ->  @Autowired注解执行注入
          
            注意:如果一个类里面用到了静态代码块先初始化一些数据,而这些数据里面有一些代码又需要注入,这个时候如果有@Autowired为这些数据进行注入,会出现空指针异常,这个时候需要使用@PostConstruct注解(JDK8及以前有)

*/

⚡扩展@PostConstruct的使用(@Autowired,构造方法,@PostConstruct的执行顺序)⚡

        "场景:当我们一个类里面有@Autowired注解注入对象,有构造方法,构造方法里面对象需要用@Autowired注解进行注入,这个时候会出现这个对象注入不成功为null,出现空指针异常,这个时候就需要@PostConstruct注解"      
            
            
            
         "@PostConstruct只有JDK8及以前有"
            
/*
   静态代码块也是一样的道理
*/

⚡扩展问题演示与解决

"问题:"
    
   public class AbController {

    @Autowired
    private AbService abService;

    public  AbController(){

        abService.find();  //这里其实是为null,因为构造方法会先执行,然后再执行@Autowired,就会导致这个对象没有被注入报错
    }
}
------------------------------------------------------------------------------------------------------------
    
"解决:"
    
 /*
    把代码放出构造方法外面,并里面在@Autowired注入对象后使用即可
 */

public class AbController  {
    @Autowired
    private AbService abService;

    public  AbController(){
    }


    @PostConstruct  //@PostConstruct注解来完成初始化, @PostConstruct注解的方法将会在abService注入完成后被自动调用
    public void init() {
        abService.find();
    }

}

/*

  执行顺序 :
     
        构造方法 -> @Autowired ->  @PostConstruct
   
*/

⭐@Autowired注解演示


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

// @Component // 默认id为类名首字母小写: bookServiceImpl

@Service
public class BookServiceImpl implements BookService {

    // 自动装配,使用暴力反射,不需要提供set方法
    // 默认是按照类型装配, 如果有多个,按照名字注入
    @Autowired
    private BookDao bookDao;

//    public void setBookDao(BookDao bookDao) {
//
//        this.bookDao = bookDao;
//    }


    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}


Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇)


🍂 @Qualifier注解

                      * 使用"@Qualifier注解"开启"指定名称"装配bean
                          
                      * 直接在成员变量上面使用
                          
                          @Service
                          public class BookServiceImpl implements BookService {
                              @Autowired
                              @Qualifier("bookDao")
                              private BookDao bookDao;
                          }

                          
/*

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

*/

⭐@Qualifier注解演示

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
// @Component // 默认id为类名首字母小写: bookServiceImpl

@Service
public class BookServiceImpl implements BookService {

    // 自动装配,使用暴力反射,不需要提供set方法
    // 默认是按照类型装配, 如果有多个,按照名字注入,如果名字对不上,指定名称注入s
    @Autowired
    @Qualifier("bookDao2") // 指定自动装配 bookDao2, 必须要配合 @Autowired
    private BookDao bookDao;

//    public void setBookDao(BookDao bookDao) {
//
//        this.bookDao = bookDao;
//    }


    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}


Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇)


🍂 @Value注解

         * "用法1:"
             
                   使用 "@Value注解" 实现"简单类型  (8种基本数据类型+String) 注入"
                   
                   * 直接在成员变量上使用即可(记得配置对应的基包扫描)
                       
                         @Component
                         public class BookUtils {
                             @Value("100")
                             private int connectionNum;
                         }
------------------------------------------------------------------------------------------------------------

         * "用法2:      $:注入配置属性"
                  
                    @Value("${tag}")
                    private String tag;

------------------------------------------------------------------------------------------------------------

         * "用法3:        #表达式值"
             
             
                    @Value("#{T(java.lang.Math).random()*1000.0}")
                    private double randomNumber;              

⭐@Value注解演示

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class BookUtils {

    @Value("mysql")
    private String databaseName;

    @Value("100")
    private int connectionNumber;

    @Override
    public String toString() {
        return "BookUtils{" +
                "databaseName='" + databaseName + '\'' +
                ", connectionNumber=" + connectionNumber +
                '}';
    }
}


Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇)


Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇)


二、PropertySource注解加载properties文件


                     * 使用 "@PropertySource注解" 加载properties文件
                         
                     * 使用el表达式可获取文件里面对应的值: ${}
                     
                     * 例子 :
                             @Configuration                                                    
                             @ComponentScan("com.itheima")
                             @PropertySource("classpath:jdbc.properties")
                               public class SpringConfig {
                              
                               }


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

 
*/

⭐代码演示

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class BookUtils {
    @Value("${user.username}")
    private String databaseName;

    @Value("${user.connectionNum}")
    private int connectionNumber;

    @Override
    public String toString() {
        return "BookUtils{" +
                "databaseName='" + databaseName + '\'' +
                ", connectionNumber=" + connectionNumber +
                '}';
    }
}

------------------------------------------------------------------------------------------------------------
    
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;

@Configuration // Spring的配置类, 相当于applicationContext.xml

@ComponentScan({"com.itheima.dao", "com.itheima.service", "com.itheima.util"}) // 基包扫描

//@PropertySource注解加载properties文件
@PropertySource({"classpath:user.properties", "classpath:jdbc.properties"})


public class SpringConfig {

}



Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇)


三、第三方资源配置管理


🍁使用 @Bean注解 配置第三方资源bean

          * "@Bean注解"的作用:
                
                         1."放在方法上"
                         
                         2."将方法的返回值放到Spring容器中"
                         
                         3.可以指定对象的id,如果没有指定默认是"方法名字"
                         
                         4.如果方法有参数,它会从容器中按类型匹配的方式获取,并且传入
                             
          * "@Bean注解的属性":                  
                             
               value: bean别名和name是相互依赖关联的,value,name如果都使用的话值必须要一致;

                name: bean名称,"如果不写会默认为注解的方法名称";

            autowire:自定装配默认是不开启的,建议尽量不要开启,因为自动装配不能装配基本数据类型、字符串、数组等,
                          这是自动装配设计的局限性,并且自动装配不如依赖注入精确;
                     
           initMethod: bean的初始化之前的执行方法,该参数一般不怎么用,因为完全可以在代码中实现;

          destroyMethod:默认使用javaConfig配置的bean,如果存在close或者shutdown方法,
                        则在bean销毁时会自动执行该方法,如果你不想执行该方法,则添加@Bean(destroyMethod="")
                        来防止出发销毁方法

                             
                             
                             
                             
-----------------------------------------------------------------------------------------------------------                             
                         
          * 例子:

             @Configuration

             public class SpringConfig {
                 @Bean           // 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
                                 //直接拿方法名,不用变化
                 public DataSource dataSource() {
                     DruidDataSource ds = new DruidDataSource();   
                     ds.setDriverClassName("com.mysql.jdbc.Driver");
                     ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
                     ds.setUsername("root");
                     ds.setPassword("123456");
                     return ds;
                 }
             }


⭐代码演示

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.*;

import javax.sql.DataSource;

@Configuration // Spring的配置类, 相当于applicationContext.xml

@ComponentScan({"com.itheima.dao", "com.itheima.service", "com.itheima.util"}) // 基包扫描

//@PropertySource注解加载properties文件
@PropertySource({"classpath:user.properties", "classpath:jdbc.properties"})




public class SpringConfig {

    @Bean("ds") // 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
                //直接拿方法名,不用变化
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db?userSSL=false");
        ds.setUsername("root");
        ds.setPassword("123456");

        return ds;
    }

}

------------------------------------------------------------------------------------------------------------
    
//测试类
    @Test
    public void test04() throws SQLException {


        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);

        DataSource dataSource = (DataSource) context.getBean("ds");
        Connection conn = dataSource.getConnection();
        System.out.println("conn = " + conn);

    }    


Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇)


🍁 将独立的配置类加入核心配置

                * 方式一: 导入式 (使用"@Import注解手动加入配置类到核心配置",此注解只能添加一次,"多个数据请用数组格式")
                
                     步骤: 配置类什么都不用做,核心配置类直接使用@Import注解导入该配置类即可
                         
                            如: @Import({JdbcConfig.class, MyBatisConfig.class})
                
                * 方式二: 扫描式 (使用@ComponentScan注解扫描配置类所在的包,加载对应的配置类信息)
                         
                     步骤: 
                           1.配置类需要配置"@Configuration注解"
                               
                           2.核心配置类使用"@ComponentScan注解扫描配置类所在的包,带它上车"


⭐导入式代码演示

// Jdbc相关的配置类
import com.alibaba.druid.pool.DruidDataSource;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;


public class JdbcConfig {


    // @Bean: 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
    @Bean("ds") // 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
               // 直接拿方法名,不用变化
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db?userSSL=false");
        ds.setUsername("root");
        ds.setPassword("123456");

        return ds;
    }
}

-----------------------------------------------------------------------------------------------------------

//核心配置类

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.*;

import javax.sql.DataSource;

@Configuration // Spring的配置类, 相当于applicationContext.xml

@ComponentScan({"com.itheima.dao", "com.itheima.service", "com.itheima.util"}) // 基包扫描


//@PropertySource注解加载properties文件
@PropertySource({"classpath:user.properties", "classpath:jdbc.properties"})



@Import(JdbcConfig.class) // 方式一(推荐): @Import: 导入其他类,成为配置类

public class SpringConfig {


}




Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇)


⭐扫描式代码演示

// Jdbc相关的配置类
import com.alibaba.druid.pool.DruidDataSource;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;


@Configuration // 方式二: 扫描式, 1.让这个类成为配置类 2.扫描这个包
public class JdbcConfig {



    // @Bean: 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
    @Bean("ds") // 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
               // 直接拿方法名,不用变化
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db?userSSL=false");
        ds.setUsername("root");
        ds.setPassword("123456");

        return ds;
    }
}

------------------------------------------------------------------------------------------------------------

//核心配置类

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.*;

import javax.sql.DataSource;

@Configuration // Spring的配置类, 相当于applicationContext.xml

@ComponentScan({"com.itheima.dao",  "com.itheima.service", "com.itheima.util", "com.itheima.config"}) // 基包扫描


//@PropertySource注解加载properties文件
@PropertySource({"classpath:user.properties", "classpath:jdbc.properties"})


public class SpringConfig {


}




Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇)


🍁 简单类型与引用类型依赖注入

           * 使用"@Value注解" 进行简单类型注入
           
           * 引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象

⭐代码演示

// Jdbc相关的配置类
import com.alibaba.druid.pool.DruidDataSource;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;


public class JdbcConfig {

    @Value("${jdbc.driver}")
    private String driver;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    // @Bean: 创建第三方Bean,并且放到IoC容器中, 没有取id,使用方法名作为id
    @Bean("ds")      // id叫ds
    public DataSource dataSource(BookService service) {
        // 假设方法需要参数, IoC容器会自动帮我们注入这个参数
        System.out.println(service);

        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);

        return ds;
    }
}

Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇)


四、XML配置 和 注解配置的 区别

Spring中的依赖注入注解、第三方资源配置管理@Bean注解、XML配置 和 注解配置的区别(Spring纯注解开发中篇)


作者:KJ.JK

文章对你有所帮助的话,欢迎给个赞或者 star,你的支持是对作者最大的鼓励,不足之处可以在评论区多多指正,交流学习

相关文章

暂无评论

暂无评论...