Spring之IoC容器:通过注解的方式实现依赖注入


前言

常用注解:
@Component,用于把当前类对象存入spring容器;
@AutoWired,自动按照类型注入数据,会根据容器中的key和变量名称进行匹配;
@Qualifier,在@AutoWired的基础上,再按照指定名称注入,给类成员注入时不可单独使用,给方法注入参数时,才可以单独使用;
@Value:用于注入基本类型和String类型;
@Scop:指定bean的作用范围;
@Configuration:指定当前类是一个配置类;
@ComponentScan:指定spring在创建容器时要扫面的包;
@Bean:把当前方法的返回值当作bean对象存入容器;
@Import:导入其他配置类;
@PropertySource:用于指定properties文件的位置,之后配置类中的成员变量就可以引用文件中的值。


提示:以下是本篇文章正文内容,下面案例可供参考

环境说明

1、pom文件的依赖

<dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.7</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>

2、spring的xml文件的配置

<?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">
</beans>

一、借助xml文件实现的注解

1、Dao层的实现类:添加的两个注解@Component @Autowired,届时spring在获取到xml配置文件后,会根据配置文件内的信息读取到对应的类以此创建对象和注入数据

package com.mediacomm.dao;

@Component(value = "userDao")
public class UserDaoImpl implements UserDao{
  @Autowired
  private QueryRunner queryRunner ;

  public List<User> findAll() throws SQLException {
    return queryRunner.query("select * from user",new BeanListHandler<User>(User.class));
  }

  public User findUserById(User user) throws SQLException{
    return queryRunner.query("select * from user where id = ?",new BeanHandler<User>(User.class),user.getId());
  }
}

2、修改xml配置文件,由于需要注入一个QueryRunner对象,而QueryRunner对象创建的时候传入DataSource连接池对象,因此配置如下

<?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">
	<!--创建连接池对象-->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/day17"></property>
        <property name="user" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>
    <!--创建QueryRunner对象-->
    <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>
    <!--让spring知道去读取那个包下的类文件的注解-->
<context:component-scan base-package="com.mediacomm.dao"></context:component-scan>

3、同样的方法配置完service层的UserServiceImpl的类,进行测试
(1)创建IoC核心容器对象
(2)根据id查找容器中的对象

public class SpringByXMLTest {
  private ApplicationContext context;
  private UserDao userDao;
  private UserService service;
  @Before
  public void init(){
    context = new ClassPathXmlApplicationContext("Spring.xml");
    //context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
    userDao = context.getBean("userDao",UserDao.class);
    service = context.getBean("userService",UserService.class);
  }
  @Test
  public void test01(){
    List<User> users = service.findAll();
    for (User user:users) {
      System .out.println(user);
    }
  }
  
七月 20, 2021 6:56:25 下午 com.mchange.v2.log.MLog <clinit>
信息: MLog clients using java 1.4+ standard logging.
七月 20, 2021 6:56:26 下午 com.mchange.v2.c3p0.C3P0Registry banner
信息: Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]
七月 20, 2021 6:56:26 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge2xaai1i9e3nwqcb2vr|7b9a4292, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge2xaai1i9e3nwqcb2vr|7b9a4292, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://192.168.0.143:3306/day17, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
User(username=admin, password=admin, address=新西兰, id=1)
User(username=ffff, password=123456, address=水星, id=2)
User(username=改改, password=321, address=成交价.., id=4)

说明一下@Qualifier的用法:
如果xml文件中配置的QueryRunner对象的id跟UserDaoImpl类中自动注入的成员变量名不相同,那个这个时候可以在上面加上@Qualifier(“xxx”)来指定对应IoC容器中对象的id。

@Component(value = "userDao")
public class UserDaoImpl implements UserDao{
  @Autowired
  @Qualifier("query1")
  private QueryRunner queryRunner ;
<!--创建QueryRunner对象-->
    <bean id="query1" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">

二、借助类文件实现的注解

1、新建类文件SpringConfig.java
@Configuration指明这是一个配置类,@ComponentScan({“com.mediacomm”})让spring届时扫面指定包下的类来读取注解,@PropertySource(“classpath:jdbcProperties.properties”)指定读入Properties文件的位置

@Configuration
@ComponentScan({"com.mediacomm"})
@PropertySource("classpath:jdbcProperties.properties")
public class SpringConfiguration {

}

2、新建jdbcProperties.properties文件

JDBC_Driver=com.mysql.jdbc.Driver
JDBC_Url=jdbc:mysql://localhost:3306/day17
JDBC_User=root
JDBC_Password=123456

3、修改SpringConfig.java
@Value获取properties文件中的值,@Bean(“dataSource”)创建对象并指定id,@Scope(“prototype”)指定对象作用范围为多例,被@Bean标识后的方法,如果需要传入参数,spring会根据参数的变量名去容器中查找有没有可用的bean对象。

@Configuration
@ComponentScan({"com.mediacomm"})
@PropertySource("classpath:jdbcProperties.properties")
public class SpringConfiguration {
  @Value("${JDBC_Driver}")
  private String driver;
  @Value("${JDBC_Url}")
  private String url;
  @Value("${JDBC_User}")
  private String user;
  @Value("${JDBC_Password}")
  private String password;
  @Bean("queryRunner")
  @Scope("prototype")
  public QueryRunner createQueryRunner(DataSource dataSource){
    return new QueryRunner(dataSource);
  }
  @Bean("dataSource")
  public DataSource createDataSource() throws PropertyVetoException {
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    dataSource.setDriverClass(driver);
    dataSource.setJdbcUrl(url);
    dataSource.setUser(user);
    dataSource.setPassword(password);
    return dataSource;
  }
}

4、进行测试
这里创建IoC容器对象的方式是new AnnotationConfigApplicationContext(SpringConfiguration.class)。

public class SpringByXMLTest {
  private ApplicationContext context;
  private UserDao userDao;
  private UserService service;
  @Before
  public void init(){
    //context = new ClassPathXmlApplicationContext("Spring.xml");
    context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
    userDao = context.getBean("userDao",UserDao.class);
    service = context.getBean("userService",UserService.class);
  }
  @Test
  public void test01(){
    List<User> users = service.findAll();
    for (User user:users) {
      System .out.println(user);
    }
  }

@Import标签是当你有多个类配置文件时,用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解。

总结

总的来说,个人偏向于使用第一种方式,可以通过xml文件更加清晰的呈现,方便以后的修改和阅读。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值