spring的常用注解:
bean定义
public class MyBean {
}
/**
* bean注入
* {@link MyBean}
*/
@Configuration
public class MyConfig {
@Bean
public MyBean getMyBean(){
return new MyBean();
}
@Bean("bean2")
public MyBean myBean2(){
return new MyBean();
}
}
测试
@SpringBootApplication(scanBasePackages = "com.anocation.beanConfig")
@RestController
public class BeanApp{
public static void main(String[] args){
SpringApplication.run(BeanApp.class);
}
@Autowired
ApplicationContext context;
@GetMapping("/print")
public String printBeans(){
String[] names = context.getBeanNamesForType(MyBean.class);
for (String name : names) {
System.out.println(name);
}
return "";
}
}
打印
getMyBean
bean2
依赖注入(设值注入)
-
@Autowired 默认根据类型获取bean,如果存在多个则按照属性名查找
-
@Resource 默认根据名称进行注解
public class InjectBean {
private String id;
public InjectBean(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
/**
* 依赖注入
* {@link InjectBean}
*/
@Configuration
public class InjectBeanConfig {
@Bean
public InjectBean myBean1(){
return new InjectBean("1");
}
@Bean
public InjectBean myBean2(){
return new InjectBean("2");
}
}
使用
@Resource(name = "myBean1")
InjectBean myBean1;
@Autowired //默认根据类型获取bean,如果存在多个则按照属性名查找
InjectBean myBean2;
构造注入(需要用@Autowired )
//构造注入
InjectBean myBean;
@Autowired
public BeanApp(InjectBean myBean2) {
this.myBean = myBean2;
}
@Primary
@Configuration
public class PrimaryBeanConfig {
@Bean
@Primary //主要的
public PrimaryBean primaryBean1(){
return new PrimaryBean("1");
}
@Bean
public PrimaryBean primaryBean2(){
return new PrimaryBean("2");
}
}
使用
@Autowired
PrimaryBean bean;
@GetMapping
public String primary(){
System.out.println(bean.getId());
return "";
}
@Scope --bean的作用域
/**
* bean的作用域
* {@link ScopeBean}
*/
@Configuration
public class ScopeBeanConfig {
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)//非单态
public ScopeBean scopeBean1(){
return new ScopeBean();
}
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)//单态
public ScopeBean scopeBean2(){
return new ScopeBean();
}
}
使用
// 非单态每次都返回一个新的实例
@GetMapping("/scope")
public String scope(){
System.out.println("非单态:"+context.getBean("scopeBean1"));
System.out.println("单态:"+context.getBean("scopeBean2"));
//非单态:com.anocation.vo.ScopeBean@4b100739
//单态:com.anocation.vo.ScopeBean@5fce816b
//非单态:com.anocation.vo.ScopeBean@413ac5e8
//单态:com.anocation.vo.ScopeBean@5fce816b
//非单态:com.anocation.vo.ScopeBean@697a5a81
//单态:com.anocation.vo.ScopeBean@5fce816b
return "";
}
//注入一个非单态的bean
@Autowired
private ScopeBean scopeBean1;
//springmvc的控制器是单态的,多次调用会是同一个实例
@GetMapping
public String scopeBean1(){
System.out.println(scopeBean1);
return "";
}
方法注入
使用场景:一个单态的bean使用一个非单态度的bean
- 方法一
private ScopeBean getScopeBean(){
//通过注入的ApplicationContext返回非单态的bean
return (ScopeBean) context.getBean("scopeBean1");
}
@GetMapping
public String getScopeBean1(){
System.out.println(getScopeBean());
return "";
}
-
方法二
@Lookup("scopeBean1") public abstract ScopeBean createScopeBean(); @GetMapping public String lookupCreateScopeBean(){ System.out.println(createScopeBean()); return ""; }
AOP注解
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
@Aspect
@Component
public class AopProxyConfig {
//*: 匹配任意数量的字符
//..:一般用于匹配任意数量的子包或参数
@Pointcut("execution(* com.anocation.Testcontroller..*.*(..))")
private void Pointcut(){}
@Before("Pointcut()")
public void before(){
System.out.println("调用前");
}
@After("Pointcut()")
public void after(){
System.out.println("调用后");
}
}
public static void main(String[] args){
//默认使用CGLIB代理
//spring.aop.proxy-target-class=false,将使用jdk动态代理
new SpringApplicationBuilder(BeanApp.class)
.properties("spring.aop.proxy-target-class=false")
.run();
}
@ComponentScan
@SpringBootConfiguration
@EnableAutoConfiguration
//@ComponentScan(basePackages = "com.anocation.beanConfig")
@ComponentScan(basePackages = "com.anocation.beanConfig"
,excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = MyConfig.class)})
@RestController
public class ScanApp {
public static void main(String[] args){
SpringApplication.run(ScanApp.class);
}
@Autowired
private ApplicationContext context;
//org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'bean2' available
@GetMapping
public String scan(){
System.out.println(context.getBean("bean2"));
return "";
}
}
spring高级注解
限定注解 -- @Qualifier
@Configuration
public class beanConfig {
@Bean
public MyBean2 myBeanA(){
return new MyBean2("a");
}
@Bean
public MyBean2 myBeanB(){
return new MyBean2("b");
}
}
/**
* 限定注解
*/
@SpringBootApplication(scanBasePackages = "com.anocation.beanConfig2")
@RestController
public class QualifierController {
public static void main(String[] args){
SpringApplication.run(QualifierController.class);
}
@Autowired
@Qualifier("myBeanA")//指定注入名称为myBeanA的bean
MyBean2 myBean;
@GetMapping
public String myBeanA(){
System.out.println(myBean.getId());
return "";
}
}
自定义限定注解
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface AnimalQualifier {
String type();
}
@Configuration
public class CustomConfig {
@Bean
@AnimalQualifier(type = "dog")
public MyBean2 dogBean(){
return new MyBean2("Tyke");
}
@Bean
@AnimalQualifier(type = "cat")
public MyBean2 catBean(){
return new MyBean2("Tom");
}
}
使用
@Autowired
@AnimalQualifier(type = "cat")
private MyBean2 myBean;
@GetMapping
public String myBeanA(){
System.out.println(myBean.getId());
return "";
}
自定义bean的生命周期--通过自定义Scope实现
public class ScopeBean {
}
/**
* 自定义Scope
* import org.springframework.beans.factory.config.Scope;
*/
public class MyScope implements Scope {
// 记录bean的使用次数
private Map<String, Integer> beanCounts = new HashMap<>();
//保存实例
private Map<String, Object> beans = new HashMap<>();
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
if (beanCounts.get(name)==null){
beanCounts.put(name,0);
}
Integer beanCount = beanCounts.get(name);
if (beanCount==0){
Object object = objectFactory.getObject();
beans.put(name,object);
}
Object bean = beans.get(name);
Integer newBeanCount = beanCount+ 1;
if (newBeanCount>=4){
newBeanCount = 0;
}
beanCounts.put(name,newBeanCount);
return bean;
}
@Override
public Object remove(String s) {
return null;
}
@Override
public void registerDestructionCallback(String s, Runnable runnable) {
}
@Override
public Object resolveContextualObject(String s) {
return null;
}
@Override
public String getConversationId() {
return null;
}
}
/**
* 自定义范围配置器
*/
@Configuration
public class ScopeConfig {
@Autowired
BeanFactory factory;
@PostConstruct
public void customScopeConfigurer(){
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
configurer.addScope("four",new MyScope());
configurer.postProcessBeanFactory((ConfigurableListableBeanFactory) factory);
}
@Bean
@Scope(scopeName = "four")
public ScopeBean scopeBeanA(){
return new ScopeBean();
}
}
使用
@Autowired
private ApplicationContext context;
@GetMapping
public String scope(){
for (int i = 0; i < 6; i++) {
System.out.println(context.getBean("scopeBeanA"));
}
//com.anocation.vo.ScopeBean@1ae3b695
//com.anocation.vo.ScopeBean@1ae3b695
//com.anocation.vo.ScopeBean@1ae3b695
//com.anocation.vo.ScopeBean@1ae3b695
//com.anocation.vo.ScopeBean@70a28b2d
//com.anocation.vo.ScopeBean@70a28b2d
return "";
}
springmvc注解
@MatrixVariable --矩阵变量
@Configuration
public class MyWebConfig extends WebMvcConfigurationSupport {
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
final RequestMappingHandlerMapping requestMappingHandlerMapping = super
.requestMappingHandlerMapping();
//设置不删除分号内容 ,即开启矩阵变量的支持
requestMappingHandlerMapping.setRemoveSemicolonContent(false);
return requestMappingHandlerMapping;
}
}
@SpringBootApplication(scanBasePackages = "com.anocation.matrixConfig")
@RestController
public class MatrixController {
public static void main(String[] args){
SpringApplication.run(MatrixController.class);
}
// http://localhost:8080/car/100;color=red;year=1000
@GetMapping("/car/{id}")
public String path(@PathVariable Integer id,
@MatrixVariable String color,
@MatrixVariable String year){
System.out.println("id = " + id);
System.out.println("color = " + color);
System.out.println("year = " + year);
//id = 100
//color = red
//year = 1000
return "";
}
}
文件上传
@RequestMapping("/upload")
public String upload(@RequestParam("file")MultipartFile file) throws IOException {
System.out.println(file.getBytes());
return "";
}
<form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit">
</form>
springboot的条件注解
类条件注解
当类路径中存在或不存在某个类时,再决定是否执行自动配置
@Configuration
public class OnClassConfig {
@Bean
@ConditionalOnMissingClass(value = "com.anocation.vo1.MyBean")
public MyBean myBean(){
return new MyBean();
}
@Bean
@ConditionalOnClass(name = "com.anocation.vo.MyBean2")
public MyBean2 myBean2(){
return new MyBean2("a");
}
}
@SpringBootApplication(scanBasePackages = "com.anocation.onclass")
@RestController
public class OnClassConfigApp {
public static void main(String[] args){
SpringApplication.run(OnClassConfigApp.class);
}
@Autowired
private ApplicationContext context;
@GetMapping
public String test(){
System.out.println(context.getBeansOfType(MyBean.class).size());
System.out.println(context.getBeansOfType(MyBean2.class).size());
return "";
}
}
自定义条件注解
/**
* import org.springframework.context.annotation.Condition;
*/
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment env = context.getEnvironment();
String user = env.getProperty("jdbc.user");
System.out.println(user);
if ("root".equals(user)){
return true;
}
return false;
}
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(MyCondition.class)
public @interface ConditionOnMyTerm {
}
@ConditionOnMyTerm
@Configuration
public class MyConfig {
@Bean
public MyBean myBean(){
return new MyBean();
}
}
application.properties
jdbc.user=123
使用
@SpringBootApplication(scanBasePackages = "com.anocation.condition")
@RestController
public class ConditionOnMyTermApp {
public static void main(String[] args){
SpringApplication.run(ConditionOnMyTermApp.class);
}
@Autowired
private ApplicationContext context;
@GetMapping
public String test(){
System.out.println(context.getBeansOfType(MyBean.class).size());
return "";
}
}