介绍
Spring对于创建生成和装载上下文的bean提供了三种配置方案,即java显式配置、隐式的bean发现机制和自动装配(自动配置)、Xml显式配置,这三种配置方案能够让我们很方便的实现DI(依赖注入)。但是在实际当中,我们可能不仅仅使用其中的一种,在复杂的大型的应用当中,我们往往将这几种方案混合使用,具体还看项目的需要。下面简单介绍一下这三种配置方案。
-
Java显式配置
Java显式配置是一种纯Java代码配置,当然是相对Xml显式配置来说的。一般情况下我们喜欢使用自动配置的方式,因为代码量少,省了很多工作。但是如果我们需要使用第三方库的时候,我们无法在源码中加入@Component和@Autowired,这时候就必须使用显式配置方案,Java显式配置或者Xml显式配置。 -
自动配置
这是一种非常方便的和强大的配置方案,它应该包括两方面: -
组件扫描(component scanning) : Spring会自动的发现山下文中所创建的bean
-
自动装配(autowiring): Spring自动满足bean之间的依赖关系。
一般情况下,推荐使用这种方式,在Spring配置方案-Spring自动配置章节我们会进行详细介绍。
- Xml显式配置
Spring最初是使用Xml进行配置的,是Spring的标配,但是它没有其他两种配置强大,在更高的Spring版本中,不推荐使用Xml配置。
为了弄明白Java显式配置,下面是一个实际的例子。假设我们有一个任务,其接口为DutyInter,实现该接口的类是Duty。而处理该任务的处理类是Handleclass,它实现了Handleinter接口。现在,我们需要将我们的任务注入到处理类中进行处理。实现的代码如下。
DutyInter接口:
package lrf.spring.duty;
/**
* 这个任务只自定义了一个方法
*
* @author lirufeng
* @date 2019/2/15 10:20
*/
public interface DutyInter {
void say();
}
Duty类:
package lrf.spring.duty;
/**
* 实现DutyInter接口
*
* @author lirufeng
* @date 2019/2/15 10:21
*/
public class Duty implements DutyInter {
@Override
public void say() {
System.out.println("I am Interface1");
}
}
Handleinter接口:
package lrf.spring.handle;
/**
* TODO
*
* @author lirufeng
* @date 2019/2/15 10:23
*/
public interface Handleinter {
void handleduty();
}
Handleclass类:
package lrf.spring.handle;
import lrf.spring.duty.DutyInter;
/**
* 实现Handleinter接口
*
* @author lirufeng
* @date 2019/2/15 10:24
*/
public class Handleclass implements Handleinter {
private DutyInter inter;
public Handleclass(DutyInter inter) {
this.inter = inter;
}
@Override
public void handleduty() {
inter.say();
}
}
在Handleclass类中,我们希望通过构造函数将DutyInter 实例注入进来,也就是说,Handleclass依赖DutyInter 的bean,因此我们需要进行bean之间依赖的配置,配置代码如下。
package lrf.spring.config;
import lrf.spring.duty.Duty;
import lrf.spring.duty.DutyInter;
import lrf.spring.handle.Handleclass;
import lrf.spring.handle.Handleinter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* java配置类
*
* @author lirufeng
* @date 2019/2/15 10:26
*/
@Configuration()
public class ConfigClass {
/**
* 第一种方式直接调用iconfig()方法
* @return
*/
// @Bean
// public Handleinter hconfig() {
// return new handleclass(iconfig());
// }
/**
* 第二种方法 参数为Interface1 当Spring调用hconfig()创建Handleinter bean的时候
* 会自动装配一个Interface1到配置方法中
* 建议使用这种方法
* @param dutyInter
* @return
*/
@Bean
public Handleinter hconfig(DutyInter dutyInter) {
return new Handleclass(dutyInter);
}
@Bean
public DutyInter iconfig() {
return new Duty();
}
}
这里配置了依赖关系,将DutyInter bean给Handleclass构造函数,即注入进去。但是这里hconfig()方法我们有两种实现方式,第一种是直接调用方法iconfig(),第二种是将DutyInter作为 hconfig()的参数,但Spring调用hconfig()方法创建Handleinter bean时,会自动装载DutyInter bean到配置中。这两种方法所达到的效果是一样的。但是第二种是最佳的选择。因为它并没有要求DutyInter bean要配置在同一个配置类中,甚至,它可以利用自动配置或者xml配置来进行配置。
Spring的java显式配置就是这么简单,通过上面的这些简单的代码,我们就可以使用了。下面是JUnit的一个测试。
import lrf.spring.config.ConfigClass;
import lrf.spring.handle.Handleinter;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertNotNull;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ConfigClass.class)
public class JavaConfigTest {
@Autowired
Handleinter handleinter;
/**
* 测试是否创建了Handleinter bean
*/
@Test
public void test() {
assertNotNull(handleinter);
}
/**
* 测试调用方法
*/
@Test
public void test1() {
handleinter.handleduty();
}
}
运行test()方法,我们得到了正确的结果,表明我们的配置生效了,如下:
我们可以调用我们的方法进行测试了
从结果可以看出,我们得到了正确的结果,表明我们成功了。Spring的java显式配置就是这么简单,如需要源码,请自行从我的git下载。地址如下
https://github.com/geeeeet/SpringJavaConfig.git