Spring(2)Spring从零到入门 - Spring注解开发(以IoC/DI为核心)

Spring(2)Spring从零到入门 - Spring注解开发(以IoC/DI为核心)

文章目录

  • Spring(2)Spring从零到入门 - Spring注解开发(以IoC/DI为核心)
    • 3 Spring之IOC/DI注解开发
      • 3.1 注解开发定义bean
        • 3.1.1 基础环境
        • 3.1.2 注解开发定义bean
      • 3.2 纯注解开发
      • 3.3 注解开发bean作用范围与生命周期管理
        • 3.3.1 bean的作用范围
        • 3.3.2 bean的生命周期
      • 3.4 注解开发依赖注入
        • 3.4.1 注解实现按照类型注入
        • 3.4.2 注解实现按照名称注入
          • 3.4.2.1 在原注解上备注该bean对象名称
          • 3.4.2.2 @Qualifier指定注入哪个名称的bean对象
        • 3.4.3 简单数据类型注入
        • 3.4.4 注解读取properties配置文件
      • 3.5 IOC/DI注解开发管理第三方bean
        • 3.5.1 注解开发管理第三方bean
        • 3.5.2 引入外部配置类
          • 步骤1:在Spring的配置类上添加包扫描
          • 步骤2:在JdbcConfig上添加配置注解
          • 步骤1:去除JdbcConfig类上的注解
          • 步骤2:在Spring配置类中引入
          • 步骤3:运行程序
        • 3.5.3 注解开发实现为第三方bean注入资源
          • 3.5.3.1 简单数据类型
          • 3.5.3.2 引用数据类型
      • 3.6 注解开发总结
      • 3.7 Spring归纳
      • 3.6 注解开发总结
      • 3.7 Spring归纳

3 Spring之IOC/DI注解开发

3.1 注解开发定义bean

3.1.1 基础环境
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency>
</dependencies>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="bookDao" class="com.baidu.dao.impl.BookDaoImpl"/>
</beans>
public interface BookDao {public void save();
}
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ..." );}
}
public interface BookService {public void save();
}public class BookServiceImpl implements BookService {public void save() {System.out.println("book service save ...");}
}
public class App {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");bookDao.save();}
}
3.1.2 注解开发定义bean

步骤1:删除原XML配置

将配置文件中的<bean>标签删除掉

<bean id="bookDao" class="com.baidu.dao.impl.BookDaoImpl"/>

步骤2:Dao上添加注解

在BookDaoImpl类上添加@Component注解

@Component("bookDao")
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ..." );}
}

注意:@Component注解不可以添加在接口上,因为接口是无法创建对象的。

XML与注解配置的对应关系: 一个注解类就相当于一个Bean

1629990315619

步骤3: 配置Spring的注解包扫描

为了让Spring框架能够扫描到写在类上的注解,需要在配置文件上进行包扫描

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><context:component-scan base-package="com.baidu"/>
</beans>

说明:

component-scan

  • component:组件,Spring将管理的bean视作自己的一个组件
  • scan:扫描

base-package指定Spring框架扫描的包路径,它会扫描指定包及其子包中的所有类上的注解。

  • 包路径越多[如:com.baidu.dao.impl],扫描的范围越小速度越快
  • 包路径越少[如:com.baidu],扫描的范围越大速度越慢
  • 一般扫描到项目的组织名称即Maven的groupId下[如:com.baidu]即可。

步骤4:运行程序

运行App类查看打印结果

image-20231220154703389

步骤5:Service上添加注解

在BookServiceImpl类上也添加@Component交给Spring框架管理

@Component
public class BookServiceImpl implements BookService {private BookDao bookDao;public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}public void save() {System.out.println("book service save ...");bookDao.save();}
}

步骤6:运行程序

在App类中,从IOC容器中获取BookServiceImpl对应的bean对象,打印

public class App {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");System.out.println(bookDao);//按类型获取beanBookService bookService = ctx.getBean(BookService.class);System.out.println(bookService);}
}

打印观察结果,两个bean对象都已经打印到控制台

image-20231220154721112

说明:

  • BookServiceImpl类没有起名称,所以在App中是按照类型来获取bean对象

  • @Component注解如果不起名称,会有一个默认值就是当前类名首字母小写,所以也可以按照名称获取,如

    BookService bookService = (BookService)ctx.getBean("bookServiceImpl");
    System.out.println(bookService);
    

对于@Component注解,还衍生出了其他三个注解**@Controller、@Service、@Repository**

通过查看源码会发现:

1630028345074

这三个注解和@Component注解的作用是一样的

目的是方便我们后期在编写类的时候能很好的区分出这个类是属于表现层、业务层还是数据层的类。

知识点: @Component等注解

名称@Component/@Controller/@Service/@Repository
类型类注解
位置类定义上方
作用设置该类为spring管理的bean
属性value(默认):定义bean的id

3.2 纯注解开发

将配置文件applicationContext.xml删除掉,使用来替换

步骤1:创建配置类

创建一个配置类SpringConfig

public class SpringConfig {
}

步骤2:标识该类为配置类

在配置类上添加@Configuration注解将其标识为一个配置类,替换applicationContext.xml

@Configuration
public class SpringConfig {
}

步骤3:用注解替换包扫描配置

在配置类上添加包扫描注解@ComponentScan替换<context:component-scan base-package=""/>

@Configuration
@ComponentScan("com.baidu")
public class SpringConfig {
}

步骤4:创建运行类并执行

创建一个新的运行类AppForAnnotation

ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
public class AppForAnnotation {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookDao bookDao = (BookDao) ctx.getBean("bookDao");System.out.println(bookDao);BookService bookService = ctx.getBean(BookService.class);System.out.println(bookService);}
}

运行AppForAnnotation,可以看到两个对象依然被获取成功

image-20231220164529415

纯注解开发,主要内容包括:

  • Java类替换Spring核心配置文件

    1630029254372

  • **@Configuration**注解用于设定当前类为配置类

  • @ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式<

    @ComponentScan({com.baidu.service","com.baidu.dao"})
    
  • 读取Spring核心配置文件初始化容器对象切换为**读取Java配置类初始化容器对象**

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

知识点1:@Configuration

名称@Configuration
类型类注解
位置类定义上方
作用设置该类为spring配置类
属性value(默认):定义bean的id

知识点2:@ComponentScan

名称@ComponentScan
类型类注解
位置类定义上方
作用设置spring配置类扫描路径,用于加载使用注解格式定义的bean
属性value(默认):扫描路径,此路径可以逐层向下扫描

小结:

  • 记住@Component、@Controller、@Service、@Repository这四个注解
  • applicationContext.xml中<context:component-san/>的作用是指定扫描包路径,注解为@ComponentScan
  • @Configuration标识该类为配置类,使用类替换applicationContext.xml文件
  • ClassPathXmlApplicationContext是加载XML配置文件
  • AnnotationConfigApplicationContext是加载配置类

3.3 注解开发bean作用范围与生命周期管理

基础环境

<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency>
</dependencies>
@Configuration
@ComponentScan("com.baidu")
public class SpringConfig {
}
public interface BookDao {public void save();
}
@Repository
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ..." );}
}
public class App {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookDao bookDao1 = ctx.getBean(BookDao.class);BookDao bookDao2 = ctx.getBean(BookDao.class);System.out.println(bookDao1);System.out.println(bookDao2);}
}
3.3.1 bean的作用范围

(1)先运行App类,在控制台打印两个一摸一样的地址,说明默认情况下bean是单例

image-20231220165601748

(2)类上添加@scope注解,使之变成非单例的

@Repository
//@Scope设置bean的作用范围
@Scope("prototype")
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}
}

知识点:@Scope

名称@Scope
类型类注解
位置类定义上方
作用设置该类创建对象的作用范围
可用于设置创建出的bean是否为单例对象
属性value(默认):定义bean作用范围,
默认值singleton(单例),可选值prototype(非单例)
3.3.2 bean的生命周期

对方法进行标识,初始化方法销毁方法

添加@PostConstruct@PreDestroy注解

JDK9以后jdk中的javax.annotation包被移除了,这两个注解刚好就在这个包中,所以添加下面依赖

<dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version>
</dependency>
@Repository
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}@PostConstruct //在构造方法之后执行,替换 init-methodpublic void init() {System.out.println("init ...");}@PreDestroy //在销毁方法之前执行,替换 destroy-methodpublic void destroy() {System.out.println("destroy ...");}
}

同样,destroy只有在容器关闭的时候,才会执行。

回顾:关闭有两种方法,close关闭和注册钩子关闭。

注意:

非单例模式下容器并没有调用destory指定方法,多例模式下spring不负责销毁

知识点1:@PostConstruct

名称@PostConstruct
类型方法注解
位置方法上
作用设置该方法为初始化方法
属性

知识点2:@PreDestroy

名称@PreDestroy
类型方法注解
位置方法上
作用设置该方法为销毁方法
属性

小结

注解与配置文件的对应关系:

image-20231220171456064

3.4 注解开发依赖注入

Spring没有提供构造函数注入、setter注入对应的注解,只提供了自动装配的注解实现

基础环境

<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency>
</dependencies>
@Configuration
@ComponentScan("com.baidu")
public class SpringConfig {
}
public interface BookDao {public void save();
}
@Repository
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ..." );}
}
public interface BookService {public void save();
}
@Service
public class BookServiceImpl implements BookService {private BookDao bookDao;public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}public void save() {System.out.println("book service save ...");bookDao.save();}
}
public class App {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookService bookService = ctx.getBean(BookService.class);bookService.save();}
}

不能实现依赖注入,报错:

image-20231220194927393

原因:BookServiceImpl中的BookDao的属性,没有成功注入,(即使有相关setter函数也不起作用)为null

3.4.1 注解实现按照类型注入

在BookServiceImpl类的bookDao属性上添加@Autowired注解

@Autowired可以写在属性上,也可也写在setter方法上,推荐**写在属性上并将setter方法删除掉**

@Service
public class BookServiceImpl implements BookService {@Autowiredprivate BookDao bookDao;//	  public void setBookDao(BookDao bookDao) {
//        this.bookDao = bookDao;
//    }public void save() {System.out.println("book service save ...");bookDao.save();}
}

为什么setter方法可以删除呢?

  • 自动装配基于反射设计创建对象并通过暴力反射为私有属性进行设值
  • 普通反射只能获取public修饰的内容
  • 暴力反射除了获取public修饰的内容还可以获取private修改的内容
  • 所以此处无需提供setter方法

如果同一个类型有多个实现类,那么会报错。此时无法区分到底要注入哪一个对象

@Repository
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ..." );}
}@Repository
public class BookDaoImpl2 implements BookDao {public void save() {System.out.println("book dao save ...2");}
}

image-20231220195729963

解决办法:按照名称注入

3.4.2 注解实现按照名称注入
3.4.2.1 在原注解上备注该bean对象名称

给这两个Dao,起两个不一样的名字

@Repository("bookDao")
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ..." );}
}
@Repository("bookDao2")
public class BookDaoImpl2 implements BookDao {public void save() {System.out.println("book dao save ...2" );}
}

此时可以注入成功。

注意,此时IOC容器中同类的Bean仍有多个@Autowired默认按照类型自动装配,如果IOC容器中同类的Bean找到多个,就按照变量名和Bean的名称匹配。因为变量名叫bookDao而容器中也有一个bookDao,所以可以成功注入。

例如出现下面这种情况,就不能成功完成注入:

image-20231220200142213

报错:NoUniqueBeanDefinitionException

image-20231220200507100

3.4.2.2 @Qualifier指定注入哪个名称的bean对象
@Service
public class BookServiceImpl implements BookService {@Autowired@Qualifier("bookDao1")private BookDao bookDao;public void save() {System.out.println("book service save ...");bookDao.save();}
}

@Qualifier注解后的值就是需要注入的bean的名称

注意:@Qualifier不能独立使用,必须和@Autowired一起使用

3.4.3 简单数据类型注入

简单数据类型:基本数据类型、字符串类型

  • @Value注解,将值写入注解的参数中
  • 注意数据格式要匹配,如将"abc"注入给int值,这样程序就会报错。
@Repository("bookDao")
public class BookDaoImpl implements BookDao {@Value("baidu")private String name;public void save() {System.out.println("book dao save ..." + name);}
}

上述内容和直接赋值等效。

3.4.4 注解读取properties配置文件

@Value一般会被用在从properties配置文件中读取内容进行使用

步骤1:resource下准备properties文件

jdbc.properties

name=baidu888

步骤2: 使用注解加载properties配置文件

配置类上添加@PropertySource注解

@Configuration
@ComponentScan("com.baidu")
@PropertySource("jdbc.properties")
public class SpringConfig {
}

步骤3:使用@Value读取配置文件中的内容

@Repository("bookDao")
public class BookDaoImpl implements BookDao {@Value("${name}")private String name;public void save() {System.out.println("book dao save ..." + name);}
}

步骤4:运行程序

public class App {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookService bookService = ctx.getBean(BookService.class);bookService.save();}
}

image-20231220201939478

注意:

  • 如果读取的properties配置文件有多个,可以使用@PropertySource的属性来指定多个

    @PropertySource({"jdbc.properties","xxx.properties"})
    
  • @PropertySource注解属性中不支持使用通配符*,运行会报错

    @PropertySource({"*.properties"})
    
  • @PropertySource注解属性中可以把classpath:加上,代表从当前项目的根路径找文件

    @PropertySource({"classpath:jdbc.properties"})
    

知识点1:@Autowired

名称@Autowired
类型属性注解 或 方法注解(了解) 或 方法形参注解(了解)
位置属性定义上方 或 标准set方法上方 或 类set方法上方 或 方法形参前面
作用为引用类型属性设置值
属性required:true/false,定义该属性是否允许为null

知识点2:@Qualifier

名称@Qualifier
类型属性注解 或 方法注解(了解)
位置属性定义上方 或 标准set方法上方 或 类set方法上方
作用为引用类型属性指定注入的beanId
属性value(默认):设置注入的beanId

知识点3:@Value

名称@Value
类型属性注解 或 方法注解(了解)
位置属性定义上方 或 标准set方法上方 或 类set方法上方
作用为 基本数据类型 或 字符串类型 属性设置值
属性value(默认):要注入的属性值

知识点4:@PropertySource

名称@PropertySource
类型类注解
位置类定义上方
作用加载properties文件中的属性值
属性value(默认):设置加载的properties文件对应的文件名或文件名组成的数组

3.5 IOC/DI注解开发管理第三方bean

3.5.1 注解开发管理第三方bean

对于别人开发的第三方代码不能在原始代码上面书写注解,要怎样为其属性赋值

环境准备:

<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency>
</dependencies>
@Configuration
public class SpringConfig {
}
public interface BookDao {public void save();
}
@Repository
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ..." );}
}
public class App {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);}
}

Druid数据源的管理为例

步骤1:导入对应的jar包

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version>
</dependency>

步骤2:在配置类中添加一个方法

注意该方法的返回值就是要创建的Bean对象类型

@Configuration
public class SpringConfig {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("root");return ds;}
}

步骤3:在方法上添加@Bean注解

@Bean注解的作用是将方法的返回值制作为Spring管理的一个bean对象

@Configuration
public class SpringConfig {@Beanpublic 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("root");return ds;}
}

注意:不能使用DataSource ds = new DruidDataSource()

因为DataSource接口中没有对应的setter方法来设置属性。(即源码中要有相关的方法支持

步骤4:从IOC容器中获取对象并打印

public class App {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);DataSource dataSource = ctx.getBean(DataSource.class);System.out.println(dataSource);}
}

image-20231220203622078

如果有多个bean要被Spring管理,直接在配置类中多些几个方法,方法上添加@Bean注解即可

3.5.2 引入外部配置类

如果第三方bean都配置到Spring的配置类SpringConfig中,虽然可以,但是不利于代码阅读和分类管理

按照类别将这些bean配置到不同的配置类中

对于数据源的bean,我们新建一个JdbcConfig配置类,并把数据源配置到该类下

public class JdbcConfig {@Beanpublic 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("root");return ds;}
}

这个配置类如何能被Spring配置类加载到,并创建DataSource对象在IOC容器中?

① 使用包扫描引入

步骤1:在Spring的配置类上添加包扫描
@Configuration
@ComponentScan("com.baidu.config")
public class SpringConfig {}
步骤2:在JdbcConfig上添加配置注解

JdbcConfig类要放入到com.baidu.config包下需要被Spring的配置类扫描到

@Configuration
public class JdbcConfig {@Beanpublic 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("root");return ds;}
}

这种方式虽然能够扫描到,但是不能很快的知晓都引入了哪些配置类,不推荐使用。

② 使用@Import引入

可以不用加@Configuration注解,但是必须在Spring配置类上使用@Import注解手动引入需要加载的配置类

步骤1:去除JdbcConfig类上的注解
public class JdbcConfig {@Beanpublic 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("root");return ds;}
}
步骤2:在Spring配置类中引入
@Configuration
//@ComponentScan("com.baidu.config")
@Import({JdbcConfig.class})
public class SpringConfig {}

注意:

  • 扫描注解可以移除

    回顾 扫描注解的作用:为了让Spring框架能够扫描到写在类上的注解,需要在配置文件上进行包扫描

  • @Import参数需要的是一个数组,可以引入多个配置类。

  • @Import注解在配置类中只能写一次,下面的方式是不允许的

    @Configuration
    //@ComponentScan("com.baidu.config")
    @Import(JdbcConfig.class)
    @Import(Xxx.class)
    public class SpringConfig {}
    
步骤3:运行程序

依然能获取到bean对象并打印控制台

public class App {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);DataSource dataSource = ctx.getBean(DataSource.class);System.out.println(dataSource);}
}

image-20231220222410684

知识点1:@Bean

名称@Bean
类型方法注解
位置方法定义上方
作用设置该方法的返回值作为spring管理的bean
属性value(默认):定义bean的id

知识点2:@Import

名称@Import
类型类注解
位置类定义上方
作用导入配置类
属性value(默认):定义导入的配置类类名,
当配置类有多个时使用数组格式一次性导入多个配置类
3.5.3 注解开发实现为第三方bean注入资源

在使用@Bean创建bean对象的时候,如果方法在创建的过程中需要其他资源该怎么办?

这些资源会有两大类,分别是简单数据类型引用数据类型

3.5.3.1 简单数据类型

数据库的四要素从properties配置文件中读取

考虑如何优化下面代码

public class JdbcConfig {@Beanpublic 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("root");return ds;}
}

步骤1:类中提供四个属性

public class JdbcConfig {private String driver;private String url;private String userName;private String password;@Beanpublic 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("root");return ds;}
}

步骤2:使用@Value注解引入值

public class JdbcConfig {@Value("com.mysql.jdbc.Driver")private String driver;@Value("jdbc:mysql://localhost:3306/spring_db")private String url;@Value("root")private String userName;@Value("password")private String password;@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;}
}

或者

取jdbc.properties配置文件

1.resources目录下添加jdbc.properties

2.配置文件中提供四个键值对分别是数据库的四要素

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db
jdbc.username=root
jdbc.password=1234

3.使用@PropertySource加载jdbc.properties配置文件

@Configuration
@ComponentScan("com.baidu")
//@Import:导入配置信息
@Import({JdbcConfig.class})
@PropertySource("classpath:jdbc.properties")
//或者 @PropertySource("/jdbc.properties") 
//写@PropertySource("jdbc.properties")识别不到建立在resource下的jdbc.properties文件
public class SpringConfig {}

4.修改@Value注解属性的值,将其修改为${key},key就是键值对中的键的值

public class JdbcConfig {//1.定义一个方法获得要管理的对象@Value("${jdbc.driver}")private String driver;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String userName;@Value("${jdbc.password}")private String password;//2.添加@Bean,表示当前方法的返回值是一个bean//@Bean修饰的方法,形参根据类型自动装配@Beanpublic DataSource dataSource(BookDao bookDao){System.out.println(bookDao);DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;}
}
3.5.3.2 引用数据类型

假设在构建DataSource对象的时候,需要用到BookDao对象

如何优化/修改下面代码

public class JdbcConfig {@Beanpublic 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("root");return ds;}
}

步骤1:在SpringConfig中扫描BookDao

扫描的目的是让Spring能管理到BookDao,也就是说要让IOC容器中有一个bookDao对象

@Configuration
@ComponentScan("com.baidu.dao")
@Import({JdbcConfig.class})
public class SpringConfig {
}

注意此时的BookDaoImpl类上一定要有注入的注解@Repository

@Repository
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}
}

步骤2:在JdbcConfig类的方法上添加参数

@Bean
public DataSource dataSource(BookDao bookDao){System.out.println(bookDao);DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;
}

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

步骤3:运行程序

image-20231220222337426

3.6 注解开发总结

XML配置和注解的开发的对比

image-20231221140135948

3.7 Spring归纳

Spring有一个容器,叫做IoC容器,里面保存bean

setUrl(“jdbc:mysql://localhost:3306/spring_db”);
ds.setUsername(“root”);
ds.setPassword(“root”);
return ds;
}
}

**步骤1:在SpringConfig中扫描BookDao**扫描的目的是让Spring能管理到BookDao,也就是说要让IOC容器中有一个bookDao对象```java
@Configuration
@ComponentScan("com.baidu.dao")
@Import({JdbcConfig.class})
public class SpringConfig {
}

注意此时的BookDaoImpl类上一定要有注入的注解@Repository

@Repository
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}
}

步骤2:在JdbcConfig类的方法上添加参数

@Bean
public DataSource dataSource(BookDao bookDao){System.out.println(bookDao);DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;
}

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

步骤3:运行程序

[外链图片转存中…(img-F3u96aHk-1703147391576)]

3.6 注解开发总结

XML配置和注解的开发的对比

[外链图片转存中…(img-3I3xHU9F-1703147391576)]

3.7 Spring归纳

Spring有一个容器,叫做IoC容器,里面保存bean

在进行企业级开发的时候,其实除了将自己写的类让Spring管理之外,还有一部分重要的工作就是使用第三方的技术

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/222594.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TrustZone之安全启动与引导失败处理

一、引导和信任链 引导是任何TrustZone系统的关键部分。只有在引导流程中之前运行的所有软件组件都是可信的情况下,才能信任某个软件组件。这通常被称为信任链。下图显示了一个简化的信任链: 在我们的示例中,首先运行的代码是boot ROM。我们必须隐式信任boot ROM,因…

iPhone手机开启地震预警功能

iPhone手机开启地震预警功能 地震预警告警开启方式 地震预警 版权&#xff1a;成都高新减灾研究所 告警开启方式

2-高可用-负载均衡、反向代理

负载均衡、反向代理 upstream server即上游服务器&#xff0c;指Nginx负载均衡到的处理业务的服务器&#xff0c;也可以称之为real server,即真实处理业务的服务器。 对于负载均衡我们要关心的几个方面如下&#xff1a; 上游服务器配置&#xff1a;使用upstream server配置上…

python可以做小程序研发嘛,python能做微信小程序吗

大家好&#xff0c;给大家分享一下python可以做微信小程序开发吗&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 大家好&#xff0c;给大家分享一下用python编写一个小程序&#xff0c;很多人还不知道这一点。下面详细解释一下用python代码…

软件测试十大必问面试题(附答案和解析)

01 介绍之前负责的项目 参考答案&#xff1a;先大概描述一下这个项目是做什么的&#xff08;主要功能&#xff09;&#xff0c;包括哪些模块&#xff0c;是什么架构的&#xff08;B/S、C/S、移动端&#xff1f;&#xff09;&#xff0c;你在其中负责哪些模块的测试。期间经历了…

【Vue】el-date-picker日期范围组件(本周、本月、上周)

系列文章 【Vue】vue增加导航标签 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/134965353 【Vue】Element开发笔记 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/133947977 【Vue】vue&#xff0c;在Windows IIS平台…

智能优化算法应用:基于非洲秃鹫算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于非洲秃鹫算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于非洲秃鹫算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.非洲秃鹫算法4.实验参数设定5.算法结果6.…

光条中心线提取-Steger算法 [OpenCV]

在线结构光视觉传感器中&#xff0c;由线激光器发射出的线结构光&#xff0c;在本质上为一个连续且具有一定厚度的空间光平面&#xff0c;而在目标表面上所形成的具有一定宽度的光条特征&#xff0c;即为该光平面与目标表面相交而成的交线。在该空间光平面的厚度方向上&#xf…

IDEA创建springboot工程

选择spring boot的版本和依赖 finish创建完成 删除无用的文件

Axure中继器的使用实现表格的增删改查的自定义文件

目录 一.认识中继器 1.1.什么中继器 1.2. 中继器的组成 1.3.中继器的使用场景 二.中继器进行增删改查 三.十例表格增删改查 还有Axure这个东西许多东西需要我们去发现&#xff0c;我们需要去细心的研究&#xff0c;我们一起加油吧&#xff01;&#xff01;&#xff01;今…

福建农林大学 html +css + JavaScript 期末复习 -- 保姆级

html css JavaScript 期末复习&#xff08;保姆级复盘&#xff09; 考试题型 1、选择题 20题 30分 2、判断题 15题 15分 3、程序题 3 题 30分 4、综合题 2 题 25分 1、网页第一代文本标签&#xff08;直接上代码&#xff0c;看保姆级注解&#xff09; <!-- doctype: docum…

设计模式:循序渐进走入工厂模式

文章目录 前言一、引入二、简单工厂模式1.实现2.优缺点3.扩展 三、工厂方法模式1.实现2.优缺点 四、抽象工厂模式1.实现2.优缺点3.使用场景 五、模式扩展六、JDK源码解析总结 前言 软件设计模式之工厂模式。 一、引入 需求&#xff1a;设计一个咖啡店点餐系统。 设计一个咖啡类…

Nature 新研究发布,GPT 驱动的机器人化学家能够自行设计和进行实验,这对科研意味着什么?

文章目录 前言揭秘Coscientist不到四分钟&#xff0c;设计并改进了程序能力越大&#xff0c;责任越大 前言 有消息称&#xff0c;AI 大模型 “化学家” 登 Nature 能够自制阿司匹林、对乙酰氨基酚、布洛芬&#xff0c;甚至连复杂的钯催化交叉偶联反应&#xff0c;也能完成。 …

车牌识别技术的应用与前景展望

引言&#xff1a; 车牌识别技术作为计算机视觉和模式识别领域的重要应用之一&#xff0c;近年来得到了广泛的关注和应用。它通过采集、分析车辆的车牌信息&#xff0c;实现了自动识别、跟踪和验证等功能&#xff0c;为交通管理、安全监控等领域带来了诸多便利。本文将从几个重要…

nodejs+vue+ElementUi家政服务系统c90g5

项目中登录模块用到token家政服务平台有管理员&#xff0c;雇主&#xff0c;雇员三个角色。管理员功能有个人中心&#xff0c;雇主管理&#xff0c;雇员管理&#xff0c;资料认证管理&#xff0c;项目类型管理&#xff0c;服务项目管理&#xff0c;需求信息管理&#xff0c;服务…

全球盲盒热潮:探寻海外市场的文化风潮与商机

近年来&#xff0c;盲盒经济在全球范围内持续升温&#xff0c;其独特的营销方式以及带给消费者的刺激感&#xff0c;引发了广大消费者的热烈追捧。特别是在海外市场&#xff0c;其增长速度之快&#xff0c;让各类盲盒品牌看到了巨大的商业潜力。然而&#xff0c;盲盒市场的快速…

css图片属性,图片自适应

CSS 图片属性指南&#xff1a;background-size 和 object-fit 在前端开发中&#xff0c;使用图片是非常常见的。为了让图片在网页中显示得更好&#xff0c;CSS 提供了多种属性来调整和控制图片的大小和布局。其中&#xff0c;background-size 和 object-fit 是两个常用的属性&a…

边缘计算有哪些常用场景?TSINGSEE边缘AI视频分析技术行业解决方案

随着ChatGPT生成式人工智能的爆发&#xff0c;AI技术在业界又掀起一波新浪潮。值得关注的是&#xff0c;边缘AI智能也在AI人工智能技术进步的基础上得到了快速发展。IDC跟踪报告数据显示&#xff0c;2021年我国的边缘计算服务器整体市场规模达到33.1亿美元&#xff0c;预计2020…

搭建接口自动化测试框架python+requests+pytest

安装python&#xff08;最好是比较新比较稳定的版本&#xff09;&#xff0c;然后是python的解释器或者叫编译器pycharm安装后新建一个项目&#xff0c;以此项目为基础&#xff0c;安装依赖搭建框架。打开pycharm&#xff0c;点击左上角的File->New project->弹出如下界面…

第一部分 数理逻辑

目录 什么是命题 注意&#xff1a; 例1 下列句子中那些是命题&#xff1f; 联结词 例2 将下列命题符号化. 注意&#xff1a; 例4 设 p&#xff1a;天冷&#xff0c;q&#xff1a;小王穿羽绒服&#xff0c;将下列命题符号化 例5 求下列复合命题的真值 例如 真值表: 例&#xff1…