在学习了bean配置的注解方式后
发现有两个问题
1.对于实现类中每次调用不同的Dao中的服务 都有很多重复的代码2.解决了bean的注解配置还有一些扫描包 和 数据源等配置怎么用注解配置呢
<context:component-scan>的注解配置
先要在类里面注释@Configuration,申明该类是个配置类,即取代了config.xml
在注释@ComponentScan,取代了<context:component-scan>
注意:@ComponentScan(value={ xxx },{xxx})括号里面是个数组 如果要扫描多个包 是要用{ }的,只扫描一个就可以省略 还有可以省略value/basePackages
这时就可以去除掉config.xml的<context:component-scan>
数据库的注解配置观察数据库的配置格式,是很类似一个普通类的配置(类似Dap/Service),所以要配置的话,可以用构造方法来配置,只是上面有参数(ref是引用类型,要注入数据源) 下面的没有参数
如果只是单纯的创建这个方法 是和原来的配置是不同的
配置文件一旦配置 不仅会根据全限定类名找到对应的QueryRunner类,注入dataSource,而且还会把这个QueryRunner实例化放入Spring的IOC容器
但方法只能实例化QueryRunner,并不能自动放入Spring的IOC容器
所以要添加一个注解 ------ @Bean
@Bean:可以注入Spring的IOC容器,但我们知道里面是key:value结构,key是属性的name,value是返回的变量同理我们可以写下面的数据源配置的注解构造方法
当我们在配置@Bean(name=“dataSource”)的时候,我们会发现 之前配置createQueryRunner(DataSource dataSource)中参数的报错消失了,这就意味着配置给方法@Bean的时候,如果该方法有参数Spring会自动去找这个参数(根据类型去找,如果有多个同类型就再根据id找)
那么我们现在就可以删除掉config.xml但我们之前再Test里面还没有改掉这个ClassPathXmlApplicationContext类型(即是用xml配置的容器),而我们用注解去配置的话 就要改成AnnotationConfigApplicationContext接口实现类。里面写注解配置类
注意:基于xml配置的实例化是多例的
而基于注解配置的实例化是单例的
对于Config标签的细节在当你创建容器的时候,将配置类的字节码文件作为参数时,在该类上可以省略@Configuration注解(因为传参已经告诉了Spring该类就是配置类),但如果你有多个配置文件(比如将原来我们的config中配置jdbc数据源的那一部分剥离开来,单独创建一个配置jdbc的JdbcConfig配置类) 那么如果传参中没有加上JdbcConfig.class,那么JdbcConfig类上一定要配置@Configuration(来声明自己是个配置类),以及在config类中扫描注解@ComponentScan()加上自己所在的包(让Spring扫描到自己)中;
否则必须在传参中将自己的字节码文件也加进去(这样就直接告诉Spring了,不用再Config里面配置自己的扫描包,和在自己类上加声明配置类的注解不管是上面的哪种,其实都不好,我们更希望既能满足有一个主配置类,然后能扫描到其他的子配置类,又不想在创建容器的参数列表中写太多参数
这时候就有了新的注解@Import
数据源内容的注解配置问题:在配置类中不小心把这些信息写死了 这是不好的我们要单独创建一个jdbConfig.properties存放这些信息,那么这些信息要怎么才能取出来并设置到对应的方法中先创建JdbcContext.Properties,将数据都写在里面
再在配置类里面定义成员变量
然后用之前讲过的@value注解+Spring中${ } 来注入数据给这几个值
${ } 里面写JdbcContext.Properties对应的key,就会返回value;
那么怎么才会返回呢—就要配置最后一个读取JdbcContext.Properties的配置其中类路径的话 一定要加上class path:
这样的话 在看到@Value就回去@PropertySource(“xxx”)里面找
学了注解和xml :哪个方便用哪个
还有一个问题
在配置数据库的时候 如果我有多个数据库的话,会通过id来查找,如果两个name都不是dataSource,那么就找不到,同理@Autowired,用哪个数据源则改成哪个,但一样的我们并不像改写这个dataSource,所以也类似@Autowired,我们会多配置一个@Qualifier(在类上是不能单独使用的),这里可以
先用DataSource类型去找 找到同类型多个在根据@Qualifier里面的id去找
最后一个问题:关于测试类里面的重复代码因为是创建容器代码重复,那么我们可以把这个步骤放到一个初始化方法里面
并将这个容器定义为成员变量,那么在配置了@Before之后init会在初始化的时候创建容器,然后又是成员变量 那么每个测试方法都可以调用但是看似我们已经解决了这个问题,开始在实际开发过程中,测试和开发的角色是分开的 也就是说 编写创建spring容器的代码 是不能放到测试类里面,因为测试类是给测试人员使用,他们可能并不能看懂Spring代码
所以我们编写的这个init的方法肯定是要删掉的,那么删掉的话 在测试的代码中IAccountService as要怎么才能获得呢(现在IAccountService as=null)
这时候我们想到了 我们已经配置了IAccountService ac在Spring的IOC容器中(xml配置或者注解配置),那么我们只需要用@Autowired就可以按照类型来找到容器里面对应的bean并实例化返回
可是当我们配置后 测试 发现 它并没有去找这个as 这是为什么呢?
这时候我们就要分析 在使用Junit来测试的时候
我们的程序入口在哪(以前是main)而Junit自己集成了一个main,所以按照Junit的main执行方式是不会管我们的Spring配置(IOC容器都没有创建)。这时候我们要让Junit去创建一下Spring容器,可是使用Junit 我们是通过导入Junit的jar包 里面都是class文件 我们无法修改让他注意到我们的Spring
这时候我们就不能想着去修改Junit里面集成的原来的main,我们要用Spring整合了Junit的main方法来替换(这个main方法能够进行IOC容器的创建)只要在配置@RunWith()就可以替换Junit的main方法
只要配置ContextConfiguration()就是告知使用xml还是注解方式注意:当使用Spring 5.x的版本时,要求Junit的版本要4.12以上才行,否则会报错(只测试某个方法会报初始化错误,执行类才会报版本错误错)
基于xml的基于注解的
来源:CSDN
作者:Lishier99
链接:https://blog.csdn.net/weixin_43895667/article/details/103344544