基于注解的Spring-IoC容器配置

基于注解的IoC容器配置

有了前面基于xml的IoC容器配置,使用注解的方式来配置Ioc容器,会发现这是个简单容易的过程。简化了很多工作量,减少了很多的注入配置。

首先修改xml中配置,移除IUserService和IUserDao的配置,修改xml的架构,使用Context Schema Configuration架构

<?xml version="1.0" encoding="UTF-8"?>
<!--这里使用context schema configuration-->
<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 https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"
>


<!-- 通知spring要扫描的包 -->
<context:component-scan base-package="com"></context:component-scan>

<!--配置QueryRunner-->
<bean id="query" class="org.apache.commons.dbutils.QueryRunner" scope="prototype" > <!--线程安全:多个dao同时操作数据库,一个runner对象会存在线程安全问题,这里采用多利模式-->
<!--配置数据源-->
<constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--数据库连接信息-->
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://192.168.1.8:3306/studenms?serverTimezone=UTC"></property>
<property name="user" value="root"></property>
<property name="password" value="sa"></property>
</bean>
</beans>

使用注解@Service,@Repository,@Autowired

@Service(value = "IUserService")
public class UserserviceImpl implements IUserService {

@Autowired
private IUserDao userDao;

// your code...
}

@Repository(value = "UserDao")
public class UseDaoImpl implements IUserDao {

@Autowired
private QueryRunner query;

// your code...
}

测试代码:

public class AnnotationIoCTest {

ApplicationContext context = null;
IUserService userService = null;

@Before
public void getApplicationContext() {
context = new ClassPathXmlApplicationContext("bean.xml");
userService = context.getBean("IUserService", IUserService.class);
}

@Test
public void finAllTest() throws SQLException {
List<UserEntity> entityList = userService.findAll();
for (UserEntity userEntity : entityList) {
System.out.println(userEntity);
}
}
}

测试结果如下: 基于注解的Spring-IoC容器配置


注意事项

  • 使用注解时,一定要在xml中使用context:component-scan,它的作用是指定spring IoC容器创建时要扫描注解的包

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

否则会抛出无法找到名叫”IUservice”的Bean:

基于注解的Spring-IoC容器配置

  • 一定要在xml配置org.apache.commons.dbutils.QueryRunner 这里可能会产生一个疑问,使用了注解@Autowried来注入QueryRunner,为什么还要在xml中配置呢?因为在QueryRunner中注入了c3p0的DataSource(数据库连接信息),如果不配置,就会无法使用c3p0,也不能连接数据库。如果仅仅在xml中配置了QueryRunner的注入,而不是用@Autowired注解,会怎么样呢?

把QueryRunner的注解去掉

 //@Autowired
private QueryRunner query;

执行测试,结果如下:

基于注解的Spring-IoC容器配置

空指针异常,没有获取到query对象,说明没有注入成功。所以这里一定要注意。

到了这里会产生僧一个疑问,不是使用注解吗,怎么还是有xml配置?接下来开始移除xml中的配置


移除xml

  • 新建一个配置类

/**
* 配置类
*/

@Configuration
@ComponentScan(value = {"com"})
public class SpringConfiguration {
}

@Configuration:标记配置类 @ComponentScan(value = {“com”}):扫描注解包,相当于xml中的

 <constructor-arg name="ds" ref="dataSource"></constructor-arg>
  • 创建QueryRunner对象并存入IoC容器

@Bean(name = "queryRunner")
@Scope(value = "prototype")
public QueryRunner instancceQueryRunner(DataSource dataSource){
return new QueryRunner(dataSource);
}

@Bean:作用是将当前方法的返回值作为一个Bean对象,存入IoC容器中。在IoC容器中Bean对象都是以Key-Value形式存储的,那么当@Bean不赋予属性时,它是的name(vaue)属性默认是当前方法名

@Scope(value = “prototype”):作用是创建多例,保证线程安全,如果这里不写@Scope注解或者不写属性或者Scope(value = “singleton”),那么创建的Bean对象默认是单例,存在着线程安全问题。

  • 配置数据源

 @Bean(name = "dataSource")
public DataSource instanceDataSource() throws PropertyVetoException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
comboPooledDataSource.setJdbcUrl("jdbc:mysql://192.168.1.8:3306/studenms?serverTimezone=UTC");
comboPooledDataSource.setUser("root");
comboPooledDataSource.setPassword("sa");
return comboPooledDataSource;
}

这里存在一个问题 基于注解的Spring-IoC容器配置创建QueryRunner对象的方法的参数报错,这是为什么?写一个方法为什么会参数报错。这是因为使用了@Bean注解,spring会在IoC容器中找dataSource的Bean对象,他没有找到DataSource的Bean对象,所以才会报错。它的寻找原理和@AutoWried的机制一样,后面介绍。

将instanceDataSource的注解放开,发现错误消失 基于注解的Spring-IoC容器配置

神奇的框架!

  • 删除bean.xml文件,修改测试代码

这里和使用xml注入的测试只有一处最重要的区别,其它都一样,就是这一行:

context = new AnnotationConfigApplicationContext(SpringConfiguration.class);

区别在于AnnotationConfigApplicationContextClassPathXmlApplicationContext,从名称可以看出,这个类是用来读取注解配置的。

测试结果如下: 基于注解的Spring-IoC容器配置


原文始发于微信公众号(程序员玄之):基于注解的Spring-IoC容器配置

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/43045.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!