Spring

Spring:

1、什么是Spring

  • 官方网站:spring.io

  • spring发展到今天已经形成了一种开发生态圈,spring提供了若干个项目,每个项目用于完成特定的功能

2、Spring系统框架

4.0的版本

image-20230318130145344

3、Spring的核心概念:

  • Ioc(Inversion of Control ) 控制反转

    • 使用对象时,由主动new产生的对象转换为外部提供的对象,此过程中对象创建控制权由程序转移到外部,此思想称之为反转
  • Spring技术对IoC思想进行实现

    • Spring提供了一个容器,称为IoC容器,用来充当IoC思想的“外部
    • IoC容器负责对象的创建、初始化等一系列工作,被创建的对象或者容器在IoC中称为Bean
  • DI(Dependency Injection) 依赖注入

    • 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
  • 主要目的:充分解耦

    • 使用IoC容器管理bean(IoC)
    • 在Ioc容器中将有依赖关系的bean进行关系绑定(DI)

image-20230318132038883

  • 最终效果
    • 使用对象时不仅可以直接从IoC中直接获取,并且获取到的bean已经绑定的所有的依赖关系

4、IoC入门案列

第一步:导入spring坐标

<!--spring依赖坐标-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.24</version>
</dependency>

第二步:

定义dao层的类和接口

/**
 * @Author: AnLe
 * @Date: 2023/03/18/16:15
 */
public interface BookDan {
    public void sho();
}
/**
 * @Author: AnLe
 * @Date: 2023/03/18/16:55
 */
public class BookDanImpl implements BookDan {

    @Override
    public void sho() {
        System.out.println("book  dao sho ....");
    }
}

定义spring管理的类(接口)

/**
 * @Author: AnLe
 * @Date: 2023/03/18/16:15
 */
public interface BookDan {
    public void sho();
}
/**
 * @Author: AnLe
 * @Date: 2023/03/18/16:20
 */
public class BookServiceImpl implements BookService {

   private BookDan bookDan = new BookDanImpl();


    @Override
    public void sho() {
        bookDan.sho();
    }
}

第三步:创建Spring的xml配置文件,配置对应的Spring管理bean

<?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标签表示配置bean
    id属性表示给bean起名字
    class属性表示给bean定义类型-->

    <!--配置bean-->
    <bean id="bookDan" class="com.anle.service.BookDanImpl"/>

    <bean id="bookService" class="com.anle.service.BookServiceImpl"/>

</beans>
  • 注意:定义id属性在同一个上下文中不能重复使用

第四步:初始化IoC容器

创建一个App类进行测试

/**
 * @Author: AnLe
 * @Date: 2023/03/18/16:57
 */
public class App {
    public static void main(String[] args) {
        //获取IoC容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //获取bean
        BookService bookService = (BookService) context.getBean("bookService");
        bookService.sho();

    }

5、DI入门案列

第一步:删除使用new的形式创建对象的代码

提供set方法

/**
 * @Author: AnLe
 * @Date: 2023/03/18/16:20
 */
public class BookServiceImpl implements BookService {

    //删除dao业务层中使用的new的方式创建的dao对象
   private BookDan bookDan ;


    @Override
    public void sho() {
        bookDan.sho();
    }

    //提供对应的set方法
    public void setBookDan(BookDan bookDan) {
        this.bookDan = bookDan;
    }
}

第二步:配置service与dao之间的关系

<!--配置bean-->
<bean id="bookDan" class="com.anle.dao.impl.BookDanImpl"/>

<bean id="bookService" class="com.anle.service.impl.BookServiceImpl">
    <!--配置service与dao层的关系-->

   <!-- property标签表示配置当前bean的属性
    name属性表示配置哪一个具体的属性
    ref属性表示参照哪一个bean-->

    <property name="bookDan" ref="bookDan"/>
</bean>

第三步:测试类不用变

/**
 * @Author: AnLe
 * @Date: 2023/03/18/16:57
 */
public class App {
    public static void main(String[] args) {
        //获取IoC容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //获取bean
        BookService bookService = (BookService) context.getBean("bookService");
        bookService.sho();

    }
}

6、bean的基础配置

1、bean的基本配置

image-20230319103358136

2、bean的别名配置

image-20230319103644177

3、bean的作用范围

  • bean的作用范围就是看bean的对象是单例的还是多例的。

  • 我们可以创建一个测试类来创两个对象来比较一下他们的地址值

    /**
     * @Author: AnLe
     * @Date: 2023/03/19/10:37
     */
    public class App2 {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("baen.xml");
    
            Object bookService1 = context.getBean("bookService");
            Object bookService2 = context.getBean("bookService");
            System.out.println(bookService1);
            System.out.println(bookService2);
    
        }
    

image-20230319104542152

  • 如果想要修改对象的单例和多例只需要在配置文件中增加scope属性并修改值为prototype
<bean id="bookService" name="service service2 service3" class="com.anle.service.impl.BookServiceImpl"  scope="prototype">
作用范围的使用场景
  • 适合交给容器管理的bean
    • 表现层对象
    • 业务层对象
    • 数据层对象
    • 工具层对象
  • 不适合交给容器管理的bean
    • 封装实体的域对象

7、实例化bean的三种方式

1、bean的实例化-构造方法(常用)

  • bean的本质就是对象,创建bean使用构造方法完成。
  1. 提供可访问的构造方法(无参构造)

    我们可以创建也可以不用创建,如果我们自己没有创建JVM会自动帮我们创建,无参构造不管是私有还是共有的都可以创建。

  2. 配置

    <bean id="bookDan" name="dao bookDao2 bookDao3" class="com.anle.dao.impl.BookDaoImpl"/>
    

2、bean的实例化-静态工厂(了解)

  1. 静态工厂

    image-20230319110533675

2.配置

image-20230319110632208

3、bean的实例化-实例工厂与FactoryBean(实用)

  1. 创建FatoryBean工厂
/**
 * @Author: AnLe
 * @Date: 2023/03/19/11:15
 */
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    //代替实例化工厂中的创建对象的方法
    @Override
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }

    @Override
    public Class<?> getObjectType() {
        return UserDao.class;
    }

    //isSingleton表示创建单例和非单例的对象
        // 返回值为: true表示单例   false表示非单例
    @Override
    public boolean isSingleton() {
        return false;
    }
}
  1. 配置

    <!--使用FactoryBean实例化bean-->
    <bean id="userDao" class="com.anle.factory.UserDaoFactoryBean"/>
    

配置时配置的时FactoryBean的对象

8、bean的生命周期

  • 生命周期:从创建到销毁的过程
  • bean生命周期:bean从创建到销毁的过程
  • bean生命周期控制:在bean创建后销毁前做一些事情

第一种格式:配置

  • 提供生命周期控制方法
/**
 * @Author: AnLe
 * @Date: 2023/03/19/10:14
 */
public class BookDaoImpl implements BookDao {
    @Override
    public void sho() {
        System.out.println("book  dao ....sho ");
    }

    //表示bean的初始化对应的操作
    public void init(){
        System.out.println("init ...dao");
    }

    //表示bean的销毁方法对应的操作
    public  void  destory(){
        System.out.println("destory..dao ");
    }
}
  • 配置生命周期的控制方法

    <bean id="bookDan"  class="com.anle.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>
    

第二种:实现接口的方式

  • 实现:InitializingBean, DisposableBean接口
/**
 * @Author: AnLe
 * @Date: 2023/03/19/10:16
 */
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
    private BookDao bookDan ;


    @Override
    public void sho() {
        System.out.println("service...sho");
        bookDan.sho();
    }

    //提供对应的set方法
    public void setBookDan(BookDao bookDan) {
        this.bookDan = bookDan;
    }



    @Override
    public void destroy() throws Exception {
        System.out.println("service....destroy");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("service .... init");
    }
}

bean生命周期的过程:

  • 初始化
    1. 创建对象(内存分配)
    2. 执行构造方法
    3. 执行属性注入(set操作)
    4. 执行bean初始化方法
  • 使用bean
    1. 执行业务操作
  • 关闭/销毁容器
    • 执行bean销毁方法

bean的销毁时机

  • 容器关闭前触发bean销毁、

  • 关闭容器的方式

    • 手工关闭容器

    ClassPathXmlApplicationContext 接口的close()方法操作

    注册关闭钩子,在虚拟机退出前关闭容器在退出虚拟机

    ClassPathXmlApplicationContext 接口的registerShutdownHook()操作

    /**
     * @Author: AnLe
     * @Date: 2023/03/19/11:40
     */
    public class App4 {
        public static void main(String[] args) {
           ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("baen.xml");
    
            BookDao bookDan = (BookDao) context.getBean("bookDan");
            bookDan.sho();
    
            //关闭钩子
            /*context.registerShutdownHook();*/
    
            //关闭容器
            context.close();
        }
    }
    

9、依赖注入的方式

  • 思考:向一个类中传递数据的方式有几种?
    • 普通方法(set方法)
    • 构造方法
  • 思考:依赖注入描述了在容器中建立了bean与bane之间的依赖关系的过程,如果bean运行需要的数字或者字符串呢?
    • 引用类型
    • 简单类型(基本数据类型与string)
  • 依赖注入
    • setter注入
      • 简单类型
      • 引用类型
    • 构造器注入
      • 简单类型
      • 引用类型

setter注入

引用类型
  • 在bean中定义引用类型属性并提供对应的set方法
/**
 * @Author: AnLe
 * @Date: 2023/03/20/13:16
 */
public class BookServiceImpl implements BookService {
    private BookDao bookDao ;
    private UserDao userDao;


    @Override
    public void sho() {
        System.out.println("book....service");
        bookDao.sho();
        userDao.getUser();
    }

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

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}
  • 配置中使用property标签ref属性注入引用数据类型对象
<bean id="bookService" class="com.anle.service.impl.BookServiceImpl">
    <property name="bookDao" ref="bookDao"/>
    <property name="userDao" ref="userDao"/>
</bean>
简单类型
  • 在bean中定义引用类型属性并提供对应的set方法
public class BookDaoImpl implements BookDao {
    private String name;
    private int age;

    @Override
    public void sho() {
        System.out.println(" book .. dao "+name+",,"+age );
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
  • 在配置中使用property标签value属性注入简单的数据类型

    <bean id="bookDao" class="com.anle.dao.impl.BookDaoImpl">
        <property name="name" value="anle"/>
        <property name="age" value="21"/>
    </bean>
    

构造器注入

引用数据类型(了解)
  • 在bean中定义引用类型属性并提供对应的构造方法
/**
 * @Author: AnLe
 * @Date: 2023/03/20/14:08
 */
public class BookServiceImpl implements BookService {

    private BookDao bookDao;
    private UserDao userDao;

    @Override
    public void sho() {
        System.out.println("book...service");
        bookDao.sho();
        userDao.getUser();
    }

    public BookServiceImpl(BookDao bookDao, UserDao userDao) {
        this.bookDao = bookDao;
        this.userDao = userDao;
    }
}
  • 配置中使用constructor-arg标签ref属性注入引用类型对象
<bean id="bookDao" class="com.anle.dao.impl.BookDaoImpl">
        <constructor-arg name="name" value="anle"/>
        <constructor-arg name="age" value="20"/>
    </bean>
参数适配(了解)
  • 配置中使用constructor-arg标签type属性设置按形参类型注入
<bean id="bookDao" class="com.anle.dao.impl.BookDaoImpl">
    <constructor-arg type="java.lang.String" value="安乐"/>
    <constructor-arg type="int" value="20"/>
</bean>
  • 配置中使用constructor-arg标签index属性设置按形参位置注入
<bean id="bookDao" class="com.anle.dao.impl.BookDaoImpl">
    <constructor-arg index="0" value="anle"/>
    <constructor-arg index="1" value="20"/>
</bean>

依赖注入方式选择

  1. 强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
  2. 可以依赖使用setter注入进行,灵活性更强
  3. Spring框架建议使用构造器注入,第三方框架内部大多数都是使用构造器注入进行数据初始化的
  4. 如果有必要可以俩个同时使用,使用构造器完成强制依赖的注入,使用setter注入完成可选择依赖的注入
  5. 实际开发过程中还可以根据实际情况分析,如果受控制对象没有提供setter方法就必须使用构造器注入
  6. 自己开发的模板建议使用setter注入

10、自动装配

  • IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean的过程称为自动装配

  • 自动装配的方式

    • 按类型(常用)
    • 按名称
    • 按构造方法
    • 不启用自动装配
  • 配置中使用bean标签autowire属性设置自动装配的类型

<!-- autowire=
 "byType"按照类型自动装配
 byName按照名字进行装配
 -->
<bean id="bookService" class="com.anle.service.impl.BookServiceImpl" autowire="byType"/>

自动装配的特征:

  • 自动装配用于引用类型依赖注入,不能对简单类型进行操作
  • 使用按类型分配时,必须保证容器中相同类型bean唯一,推荐使用
  • 使用按名称分配时,必须保证容器中具有指定名称的bean,因变量名与配置融合,不推荐使用
  • 自动装配的优先级低于setter注入与构造器注入,同时出现时自动装配配置失败

11、集合注入

1、注入数组

<!--数组的注入方式-->
<property name="arr">
    <array>
        <value>100</value>
        <value>200</value>
        <value>300</value>
    </array>
</property>

2、注入list对象(重点)

<!--list集合的注入方式-->
<property name="list">
    <list>
        <value>李白</value>
        <value>张飞</value>
        <value>吕布</value>
    </list>
</property>

3、注入Map对象(重点)

<!--map的注入方式-->
<property name="map">
    <map>
        <entry key="姓名" value="阿飞"/>
        <entry key="年龄" value="22"/>
        <entry key="职业" value="板砖"/>
    </map>
</property>

4、注入set对象

<!--set的注入方式-->
<property name="set">
    <set>
        <value>张三</value>
        <value>李四</value>
        <value>王五</value>
    </set>
</property>

5、注入properties对象

<!--properties的注入方式-->
<property name="properties">
    <props>
        <prop key="四川">成都</prop>
        <prop key="上海">虹桥</prop>
        <prop key="广州">深圳</prop>
    </props>
</property>

12、数据源对象管理

  • 导坐标
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
</dependency>
  • 配置数据源对象作为spring管理的bean

    <!--管理DataSource对象-->
    <bean  class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring-stu"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>
    

13、加载properties文件

  • 开启context命名空间

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="
                   http://www.springframework.org/schema/beans
                   http://www.springframework.org/schema/beans/spring-beans.xsd
    
                    http://www.springframework.org/schema/context
                   http://www.springframework.org/schema/context/spring-context.xsd
    ">
    
  • 使用context命名空间,加载properties文件

<context:property-placeholder location="jdbc.properties"/>
  • 使用${}读取加载的属性值

    <bean  class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${driverClass}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password"/>
    </bean>
    
  • 不加载系统属性

    <context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
    
  • 加载多个properties文件

  <context:property-placeholder location="jdbc.properties,jdbc.properties2" system-properties-mode="NEVER"/>
  • 加载所有properties文件
<context:property-placeholder location="*.properties" system-properties-mode="NEVER"/>
  • 加载所有properties文件标准格式

        <context:property-placeholder location="classpath:*.properties" system-properties-mode="NEVER"/>
    
  • 从类路径jar包中搜索并加载properties文件

    <context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>
    

13、容器

1、创建容器

  • 方式一:类路径加载配置文件

    ApplicationContext Context = new ClassPathXmlApplicationContext("bean.xml");
    
  • 方式二:文件路劲加载配置文件

    ApplicationContext Context = new FileSystemXmlApplicationContext("文件的绝对路劲");
    
  • 方式三:加载多个配置文件

          ApplicationContext Context = new ClassPathXmlApplicationContext("bean.xml","bean2.xml");
    

2、获取bean的三种方式

  • 方式一:使用bean名称获取

    BookDao bookDao = (BookDao) Context.getBean("bookDao");
    
  • 方式二:使用bean名称获取并指定类型

    BookDao bookDao1 = Context.getBean("bookDao", BookDao.class);
    
  • 方式三:使用bean类型获取(保证只有一个文件的前提下)

    BookDao bean = Context.getBean(BookDao.class);
    

3、容类层次结构image-20230327221854373

4、BeanFactory(所有容器类的顶层接口)

image-20230327221956465

14、注解开发

1、注解开发定义bean

  • 使用@Component定义bean

    /**
     * @Author: AnLe
     * @Date: 2023/03/28/17:35
     */
    
    @Component("bookDao")
    public class BookDaoImpl implements BookDao {
        @Override
        public void sho() {
            System.out.println("book...dao...");
        }
    }
    
  • 核心配置文件通过组件扫描加载bean

    <!--指定要扫描的包,这个包下的注解就会生效-->
    <context:component-scan base-package="com.anle.dao"/>
    <context:annotation-config/>
    
  • spring提供@Component注解的三个衍生注解

    • @Controller:用于表现层bean定义
    • @Service:用于业务层bean定义
    • @Repostiory:用于数据层bean定义

2、纯注解开发

  • spring3.0开启了纯注解开发模式,使用Java类替代了配置文件,开启spring快熟开发赛道

  • 使用纯注解开发步骤

    • 创建一个Java类来替代spring的核心配置文件

      /**
       * @Author: AnLe
       * @Date: 2023/03/29/16:12
       */
      @Configurable
      @ComponentScan("com.anle")
      public class SpringConfig {
      
      }
      
    • 第二加上@Configurable注解,该注解表示用于设定当前类为配置类(简单来说就是告诉程序这个类是spring的配置类)

    • 第三加上@ComponentScan(“com.anle”)注解,该注解设定扫描路径,此注解只能增加一个,多个数据请用数组的格式

      这个注解代替了下面spring配置文件

      <context:component-scan base-package="com.anle"/>
      

​ 多个数据用数组的形式

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

    之前使用的

ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");

​ 使用注解的方式

ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

15、bean的作用范围和生命周期

1、bean的作用范围

  • 使用@Scope(“singleton”)注解进行,将要定义的范围以字符串的形式写到里面就行
@Scope("singleton")
public class BookDaoImpl implements BookDao {

2、bean的生命周期

  • 使用@PostConstruct、@PreDestroy定义生命周期
    • @PostConstruct表示初始化方法
    • @PreDestroy表示销毁方法
@Repository
@Scope("singleton")
public class BookDaoImpl implements BookDao {
    @Override
    public void sho() {
        System.out.println("book...dao");
    }

    @PostConstruct
    public void init(){
        System.out.println("init....");
    }

    @PreDestroy
    public void destroy(){
        System.out.println("destroy....");
    }

}

16、注解开发依赖注入

依赖注入:

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

    /**
     * @Author: AnLe
     * @Date: 2023/03/29/17:38
     */
    
    @Service
    public class BookServiceImpl implements BookService {
    
        @Autowired
        private BookDao bookDao;
    
    
        @Override
        public void sho() {
            System.out.println("book....service");
            bookDao.sho();
        }
    }
    
  • 注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有化属性初始化数据,因此无需提供setter方法

  • 注意:自动装配建议使用无参构造方法创建对象(默认),如果不提供对应 的构造方法,请提供唯一的构造方法。

  • 指定加载某一个bean使用@Qualifier(“bookDao2”)注解

    /**
     * @Author: AnLe
     * @Date: 2023/03/29/17:38
     */
    
    @Service
    public class BookServiceImpl implements BookService {
    
        @Autowired
        @Qualifier("bookDao2")
        private BookDao bookDao;
    
    
        @Override
        public void sho() {
            System.out.println("book....service");
            bookDao.sho();
        }
    }
    
  • 注意@Qualifier注解无法单独使用,必须配合 @Autowired注解一起使用

  • 简单类型的的注入使用@Value注解

/**
 * @Author: AnLe
 * @Date: 2023/03/29/17:35
 */

@Repository("bookDao")
public class BookDaoImpl implements BookDao {

    @Value("张三")
    private String name;


    @Override
    public void sho() {
        System.out.println("book....dao"+name);
    }
}
  • 加载外部文件使用@PropertySource({“jdbc.properties”})注解加载文件

    /**
     * @Author: AnLe
     * @Date: 2023/03/29/17:34
     */
    
    @Configuration
    @ComponentScan("com.anle.spring")
    @PropertySource({"jdbc.properties"})
    public class SpringConfig {
    
    }
    
  • 注意路劲仅支持单一文件配置,多文件使用数组的格式,不允许使用通配符*

  • 如果我们的值需要引用文件中的数据,那我们需要按照下面的形式。

    • 文件中的数据名称是什么在 @Value(“${}”)的括号中就填什么。
    @Repository("bookDao")
    public class BookDaoImpl implements BookDao {
    
        @Value("${name}")
        private String name;
    
    
        @Override
        public void sho() {
            System.out.println("book....dao"+name);
        }
    }
    

17、第三方bean的管理

  • 使用@Bean注解配置第三方bean
/**
 * @Author: AnLe
 * @Date: 2023/03/29/18:21
 */

@Configuration
public class SpringConfig {

    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/sping-stu");
        ds.setUsername("root");
        ds.setPassword("123456");
        return ds;
    }

}
  • 由于所有的管理都写在这个文件里面会特别的乱所有采用独立的配置

方式一:导入式(推荐)

/**
 * @Author: AnLe
 * @Date: 2023/03/29/18:21
 */

public class jdbcConfig {
    //1、定义一个方法获得要管理的对象
    //2、@Bean、表示当前方法的返回值是一个bean

    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/sping-stu");
        ds.setUsername("root");
        ds.setPassword("123456");
        return ds;
    }


}
  • 使用@Import({jdbcConfig.class})注解手动加入配置类到核心配置,此注解只能使用一次,多个数据用数组的格式。
/**
 * @Author: AnLe
 * @Date: 2023/03/29/18:21
 */

@Configuration
@Import({jdbcConfig.class})
public class SpringConfig {
    
}

方式二:扫描式(不推荐)

@Configuration
public class jdbcConfig {
    //1、定义一个方法获得要管理的对象
    //2、@Bean、表示当前方法的返回值是一个bean

    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/sping-stu");
        ds.setUsername("root");
        ds.setPassword("123456");
        return ds;
    }


}
  • 使用@ComponentScan(“com.anle.spring”)注解进行包扫描配置类所在的包,加载对应的配置类信息
/**
 * @Author: AnLe
 * @Date: 2023/03/29/18:21
 */

@Configuration
@PropertySource("com.anle")
public class SpringConfig {

}

2、第三方bean注入依赖管理

  • 简单类型的依赖注入

    /**
     * @Author: AnLe
     * @Date: 2023/03/29/18:21
     */
    public class jdbcConfig {
        //1、定义一个方法获得要管理的对象
        //2、@Bean、表示当前方法的返回值是一个bean
        @Value("com.mysql.jdbc.Driver")
        private String driver;
        @Value("jdbc:mysql://localhost:3306/sping-stu")
        private String url;
        @Value("root")
        private String username;
        @Value("123456")
        private String password;
    
    
        @Bean
        public DataSource dataSource(){
            DruidDataSource ds = new DruidDataSource();
            ds.setDriverClassName(driver);
            ds.setUrl(url);
            ds.setUsername(username);
            ds.setPassword(password);
            return ds;
        }
        
    }
    
  • 引用类型依赖注入

    @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定义方法设置形参即可,容器会根据类型自动装配对象

18、注解开发总结

  • xml配置和注解配置对比

    image-20230329192318965

19、Spring整合MyBatis

  • 第一步:导坐标

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>3.0.1</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
        <scope>compile</scope>
    </dependency>
    
  • 第二步:创建创建一个类进行配置,主要替换mybatis的xml配置

/**
 * @Author: AnLe
 * @Date: 2023/03/31/9:52
 */
public class MybatisConfig {

    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
        SqlSessionFactoryBean sfb = new SqlSessionFactoryBean();
        sfb.setTypeAliasesPackage("com.anle.domain");
        sfb.setDataSource(dataSource);
        return sfb;
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.anle.dao");
        return msc;
    }
}
  • 第三步:在Spring配置中引入该类
/**
 * @Author: AnLe
 * @Date: 2023/03/31/9:19
 */

@Configuration
@ComponentScan("com.anle")
@PropertySource({"jdbc.properties"})
@Import({jdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
}

20、Spring整合Junit

  • 第一步:导坐标

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>6.0.5</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
    </dependency>
    
  • 第二步:在测试类中引入相关的反射

/**
 * @Author: AnLe
 * @Date: 2023/03/31/10:15
 * spring整合junit
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountTest {
    @Autowired   //自动装配
    public DagImpl dag;
    @Test
     public void testById(){
        System.out.println(dag.getById(2));
      }
}
SqlSessionFactoryBean sfb = new SqlSessionFactoryBean();
    sfb.setTypeAliasesPackage("com.anle.domain");
    sfb.setDataSource(dataSource);
    return sfb;
}

@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
    MapperScannerConfigurer msc = new MapperScannerConfigurer();
    msc.setBasePackage("com.anle.dao");
    return msc;
}

}


- 第三步:在Spring配置中引入该类

```Java
/**
 * @Author: AnLe
 * @Date: 2023/03/31/9:19
 */

@Configuration
@ComponentScan("com.anle")
@PropertySource({"jdbc.properties"})
@Import({jdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
}

20、Spring整合Junit

  • 第一步:导坐标

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>6.0.5</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
    </dependency>
    
  • 第二步:在测试类中引入相关的反射

/**
 * @Author: AnLe
 * @Date: 2023/03/31/10:15
 * spring整合junit
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountTest {
    @Autowired   //自动装配
    public DagImpl dag;
    @Test
     public void testById(){
        System.out.println(dag.getById(2));
      }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值