spring tips

spring bean 多个 id

1
2
3
4
5
6
7
8
9
10
11
12
13
@Service("Service-A")
public class SampleService {
public String doSomething() { return "Foo"; }
}

@Configuration
public class SampleConfig {

@Bean(name = {"Service-B", "Service-C"})
public SampleService createMirroredService(@Autowired SampleService service) {
return service;
}
}

作用域代理——proxyMode 属性

将一个短生命周期作用域 bean 注入给长生命周期作用域 bean,我们期望长生命周期 bean 的属性保持与短生命周期 bean 同样。例如

1
2
3
4
5
6
7
8
9
10
11
@Component
@Scope(value = BeanDefinition.SCOPE_PROTOTYPE,proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Prototype {
}

@Component
@Scope(BeanDefinition.SCOPE_SINGLETON)
public class Singleton {
@Autowired
private Prototype prototype;
}

保证每次prototype都是最新的,需要在Prototype类上定义proxyMode

延迟加载 bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//...
import javax.inject.Inject;
import javax.inject.Provider;

public class InjectTest{

@Inject
Provider<InjectBean> provider;

public void test() {
InjectBean bean = provider.get();
}

}

使用@Autowire也是可以的,重要是使用了Provider

基于注解的切面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AnnotationAspect {

@Around("@annotation(Log)")
public void log1(ProceedingJoinPoint point){
MethodSignature s = (MethodSignature) point.getSignature();
Log annotation = s.getMethod().getAnnotation(Log.class);
}
}

所有注解了@Log的方法都会被切

Spring注入文件

1
2
3
4
5
6
7
8
9
import org.springframework.core.io.Resource;

@Value("classpath:rootxml.js")
private Resource cert;

@Test
public void test() throws ScriptException, IOException {
System.out.println(StreamUtils.copyToString(cert.getInputStream(), StandardCharsets.UTF_8));
}

@Autowired

@Autowired(required = false)Spring容器中没有对应的BeanDefinition时不会注入值,可赋值一个默认值避免空指针的情况。

定时任务

Spring@Scheduled  可使用crontab语法,但是不同于unix的标准语法,它第一位是秒

1
2
3
4
@Scheduled(cron = "1 22 22 * * *")
public void log() {
logger.info("--------------------" + index++);
}

cron规则一定是 6 位以空白字符间隔的字符串,其中每位代表的含义如下

1
2
3
4
5
6
7
8
秒     分   小时    日    月    星期
0-59 0-59 0-23 1-31 1-12 0-6

记住几个特殊符号的含义:
* 代表取值范围内的数字
*/x 代表每x
x-y 代表从x到y
, 分开几个离散的数字

@Primary

@Primary:自动装配时当出现多个 Bean 候选者时,被注解为@Primary 的 Bean 将作为首选者,否则将抛出异常