Spring IOC 超详细使用(2) 初学者必看 注解的使用 自动装配 连接数据库 泛型依赖注入 Spring单元测试

IOC的使用(2)

Spring超详细使用(1),内容包含各种方式获取组件、为不同类型的属性赋值、FactoryBean的使用等,传送地址:Spring IOC 超详细使用(1)

Spring AOP 的使用,传送地址:Spring AOP 的详细使用

一、引用外部属性文件

使用C3P0数据库连接池(连接的是mysql8)

  1. 导包
    在这里插入图片描述

  2. 在src目录下创建c3p0.properties文件,其中内容是:

jdbc.username=root
jdbc.password=root
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/book?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT
jdbc.driverClass=com.mysql.jdbc.Driver
//以上key是自定义的,并不是C3P0标准的key

注意:
(1) username是Spring中的一个关键字,为了防止配置文件中的key与其重名,可以为配置 文件的key加前缀
(2) 连接mysql8时,
i. 使用mysql - connector - java - 5.1.49.jar及以上版本
ii. url地址需要加后缀

  1. xml中编写

(1) 使用context名称空间加载外部配置文件

在这里插入图片描述

(2) xml中编写

     <!-- location属性固定写法:classpath表示引用类路径下的资源-->
     <context:property-placeholder location="classpath:c3p0.properties"/>
    
     <!-- 创建一个数据库连接池 -->
     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    
       <!-- ${key}动态取出配置文件中某个key对应的值 -->
    
       <property name="user" value="${jdbc.username}"></property>
       <property name="password" value="${jdbc.password}"></property>
       <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
       <property name="driverClass" value="${jdbc.driverClass}"></property>
    
    </bean>

  1. 测试
   @Test
   public void test() throws SQLException {
    
    
       ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
       DataSource dataSource = (DataSource)ioc.getBean("dataSource");
       System.out.println(dataSource.getConnection());
       //com.mchange.v2.c3p0.impl.NewProxyConnection@64c87930
   }

二、通过注解创建bean

Spring中有四个注解
(1) @Controller:推荐给控制层(Servlet)的组件加此注解
(2) @Service:推荐给业务逻辑层的组件添加此注解
(3) @Repository:推荐给数据库层(Dao层)的组件添加此注解
(4) @Component:推荐不属于以上的组件添加此注解

注意:
i. 给所要创建组件的类添加任何一个注解都可快速的将此组件添加到ioc容器的管理中
ii. 使用以上四个注解的任何一个均可,但尽量使用推荐

使用步骤:

(1) 导入aop包,以支持注解模式:

在这里插入图片描述

(2) 给所要创建组件的类添加以上注解

import org.springframework.stereotype.Service;

    @Service
    public class BookService {
    
    
       //内容
    }

(3) 让Spring自动扫描加了注解的组件,在xml文件中使用context名称空间

<!-- context:component-scan:自动扫描组件 -->
<!-- base-package:指定扫描的包,会将此包下的所有包的所有加了注解的类,自动的扫描进ioc容器中 -->
   
<context:component-scan base-package="com.qizegao"></context:component-scan>
   
<!-- com.qizegao.test 与 com.qizegao.util包都会被扫描,扫描之后符合条件的类图标会加小s -->

注意:

使用注解加入到容器中的组件,和使用配置文件加入到容器中的组件默认行为是一致的:
i. 组件的默认id是类名首字母小写
ii. 组件默认是单例的

(4) 测试

 public void test() {
    
    
    ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
    System.out.println(ioc.getBean("bookService") == ioc.getBean("bookService"));
    //true
  }

注意:
i. 可以修改组件的id
ii. 可以修改组件为多实例,如下:

@Service("newName") // 修改id为newName
  @Scope(value="prototype") // 修改bean为多实例
  public class BookService {
    
    
       //内容
  }

测试:

   public void test() {
    
    
       ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
       System.out.println(ioc.getBean("newName") == ioc.getBean("newName"));
       //false
   }

三、指定Spring扫描时不包含、只包含的组件

//不包含
   <context:component-scan base-package="com.qizegao">
       <!-- 使用context:exclude-filter指定扫描时不包含的组件:
             1. type=annotation:按照注解进行排除,使用了expression中指定的注解(全类名)就不会被包含进来
             2. type=assignable:按照指定的类进行排除,expression中指定要排除的全类名
        -->
       <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
   </context:component-scan>

//只包含
    //Spring默认是把包中所有满足条件的组件全部扫描进来,故应当先禁用默认的扫描规则
   <!-- use-default-filters="false":禁用默认的扫描规则 -->
   <context:component-scan base-package="com.qizegao" use-default-filters="false">
        <!-- 使用context:include-filter指定扫描时只包含的组件:用法与context:exclude-filter一致 -->
        <context:include-filter type="assignable" expression="com.qizegao.test.BookService"/>
   </context:component-scan>

四、使用@Autowired注解根据类型实现自动装配

自动装配:自动的为某个属性赋值,一定是去容器中找这个属性对应的组件赋值,也就要求此组件 必须在容器中,否则报错

  1. 在com.qizegao.test包下创建两个类
  @Repository
  public class BookDao {
    
    
     public void saveBook() {
    
    
         System.out.println("正在使用BookDao保存图书");
     }
  }

  @Service
  public class BookService {
    
    
   
      @Autowired
      //使用此注解自动的为其赋值,无需再new
      private BookDao bookDao;
   
      public void save() {
    
    
          System.out.println("调用BookDao保存图书");
          bookDao.saveBook();
      }
  }

  1. xml中让Spring扫描加了注解的组件
<context:component-scan base-package="com.qizegao"></context:component-scan>
  1. 测试
public void test() {
    
    
   ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
   //BookService默认是单例的,使用class获取
   BookService bookService = ioc.getBean(BookService.class);
   bookService.save();
   /**
    * 调用BookDao保存图书
    * 正在使用BookDao保存图书
    */
}

五、@Autowired注解自动装配原理

   @Autowired
   private BookDao bookDao;

先按照类型(BookDao)去容器中找对应的组件:getBean(BookDao.class):
(1) 找到一个,赋值
(2) 没有找到,抛异常
(3) 找到多个(会将此类的子类也找到):

将变量名(bookDao)作为id继续去容器中找对应的组件:
i. 匹配成功,装配
ii. 匹配失败,报错

注意:
(1)
@Autowired
@Qualifier(“xxx”) //使用此注解可以使用xxx作为id去匹配,而不是使用变量名作为id
private BookDao bookDao;

(2) 匹配到则装配,匹配不到则赋null值:@Autowired(required=false)

六、在方法上使用@Autowired

  1. 这个方法会在bean创建的时候自动运行
  2. 这个方法的每个参数都会按照上述自动注入值

(1) BookService中的方法

    //BookService与BookDao均已注册到ioc容器中
    @Service
    public class BookService {
    
    
       @Autowired(required=false)
       //参数的位置也可以使用@Qualifier注解
       public void method(@Qualifier("bookDao")BookDao bookDao) {
    
    
           System.out.println(bookDao); 
       }
    }

(2) 测试

  @Test
   public void test() {
    
    
       ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
       //运行后输出:com.qizegao.test.BookDao@2bbaf4f0
   }

七、@Autowired与 @Resource的区别

二者可以互换

@Autowired:功能最强大,是Spring定义的注解,但只支持Spring框架
@Resource:扩展性强,是Java定义的标准,如果切换成另外的容器(非Spring)也可使用

八、泛型依赖注入

注册一个组件时,它的泛型也是参考标准,如下图:

注意:注册有继承关系的组件时,只需要在子类上加注解,父类不用加会自动注入

在这里插入图片描述

九、Spring的单元测试

(1) 导包:

在这里插入图片描述

(2) 在测试类之上使用两个注解:
① @ContextConfiguration(locations=“classpath:ioc.xml”)
指定Spring配置文件的位置

② @RunWith(SpringJUnit4ClassRunner.class)
指定用哪种驱动进行单元测试,默认是Junit

(3) 好处:无需使用getBean方法获取组件,直接在要获取的组件上加注解@Autowired,Spring 会自动装配

(4) 使用案例:

 @ContextConfiguration(locations="classpath:ioc.xml")
    @RunWith(SpringJUnit4ClassRunner.class)
    public class test {
    
    
   
       @Autowired
       BookDao bookDao;
   
       @Test
       public void test() {
    
    
           System.out.println(bookDao);
           //com.qizegao.test.BookDao@62e136d3
       }
    }  


猜你喜欢

转载自blog.csdn.net/weixin_49343190/article/details/109673725