image.png
@Configuration
public class AppConfig {
@Bean
public TransferService transferService(AccountRepository accountRepository) {
return new TransferServiceImpl(accountRepository);
}
}
public class Foo {
public void init() {
// initialization logic
}
}
public class Bar {
public void cleanup() {
// destruction logic
}
}
@Configuration
public class AppConfig {
@Bean(initMethod = "init")
public Foo foo() {
return new Foo();
}
@Bean(destroyMethod = "cleanup")
public Bar bar() {
return new Bar();
}
}
#### 自定义Bean命名
默认情况下,配置类使用@Bean方法的名称作为生成的bean的名称。但是,可以使用name属性来重写此功能。
@Configuration
public class AppConfig {
@Bean(name = "myFoo")
public Foo foo() {
return new Foo();
}
}
Bean别名
@Configuration
public class AppConfig {
@Bean(name = { "dataSource", "subsystemA-dataSource", "subsystemB-dataSource" })
public DataSource dataSource() {
// instantiate, configure and return DataSource bean...
}
}
Bean描述
@Configuration
public class AppConfig {
@Bean
@Description("Provides a basic example of a bean")
public Foo foo() {
return new Foo();
}
}
@Configuration注解
@Configuration是一个类级别的注解,指明此对象是bean定义的源。@Configuration类通过public @Bean注解的方法来声明bean。在@Configuration类上对@Bean方法的调用也可以用于定义bean之间的依赖
@Configuration
public class AppConfig {
@Bean
public ClientService clientService1() {
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
}
@Bean
public ClientService clientService2() {
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
}
@Bean
public ClientDao clientDao() {
return new ClientDaoImpl();
}
}
clientDao()方法clientService1()和clientService2()被各自调用了一次,但ClientDao 只会有一个。
因为所有的@Configuration类在启动时都使用CGLIB进行子类实例化(配置类都不能是final类型),在子类中,子方法在调用父方法创建一个新的实例之前会首先检查任何缓存(作用域)的bean。
基于java组合配置
使用@Import注解
@Configuration
public class ConfigA {
@Bean
public A a() {
return new A();
}
}
@Configuration
@Import(ConfigA.class)
public class ConfigB {
@Bean
public B b() {
return new B();
}
}
public static void main(String[] args) {
//只需引入ConfigB
ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);
// now both beans A and B will be available...
A a = ctx.getBean(A.class);
B b = ctx.getBean(B.class);
}
web.xml
dispatcher
org.springframework.web.servlet.DispatcherServlet
.......
bean生命周期回调
class Foo implements InitializingBean,DisposableBean,*Aware系列的接口{
public void init() {
// initialization logic
}
}
@Configuration
public class AppConfig {
@Bean(initMethod = "init")
public Foo foo() {
return new Foo();
}
profile
-Dspring.profiles.active="profile1,profile2"
@Configuration
@Profile("default")
public class DefaultDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.build();
}
}
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {
@EnableLoadTimeWeaving?
image.png
测试
@ActiveProfiles("local")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class BaseTest {
}
@AutoConfigureMockMvc
public class SmsControllerTest extends BaseTest{
@Autowired
private MockMvc mockMvc;
@Test
public void addSign() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.multipart("/v1/api/sms/addSign")
.file(firstFile)
.param("a", param.a + "")
.andDo(print())
.andExpect(status().isOk());
}
@Test
@Transactional
@Rollback()
public void save() throws Exception {
.....
}
SpringRunner vs SpringJUnit4ClassRunner
public final class SpringRunner extends SpringJUnit4ClassRunner {
public SpringRunner(Class clazz) throws InitializationError {
super(clazz);
}
}
区别只是 SpringRunner 继承 SpringJUnit4ClassRunner