spring注解注入笔记

spring注解注入笔记

        spring注入主要使用两个注解: @Configuration和@Bean.

     @Configuration注解

        先来看下其注解的限制
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component

        可以看出@Configuration注解的使用范围是接口,类,枚举和注解,他实际上就相当于XML配置中的beans标签.这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器.

        注意:

        1.    使用该注解的是类不能使final类或者匿名类.

        2.    被注释的类中被@Configuration注解的内部类必须是静态类

     @Bean

        先来看下其注解的限制
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented

        可以看出@Bean注解的使用范围是用在方法和注解上.它实际上就相当于XML配置中的bean标签.被注册的bean默认是单例的,如果要配置成多例.则需要用到@Scope("prototype").

        注入的时候就会有其初始化和销毁的方法,可以在Bean方法中添加init()和destroy(),然后在配置类中声明其初始化方法和销毁方法即会在初始化或者销毁的时候调用.

         被测试类 

package com.yczuoxin.demo.config;

public class BeanService {

    public void init(){
        System.out.println("Bean-init-method");
    }

    public BeanService(){
        System.out.println("初始化构造函数-BeanService");
    }

    public void destroy(){
        System.out.println("Bean-destroy-method");
    }
}
配置类:
package com.yczuoxin.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.yczuoxin.demo.config")
public class PrePostConfig {

    @Bean(initMethod = "init", destroyMethod = "destroy")
    BeanService beanWayService(){
        return new BeanService();
    }
}
测试类:
package com.yczuoxin.demo.config;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class DemoTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PrePostConfig.class);
        BeanService beanService = context.getBean(BeanService.class);
        context.close();
    }
}
初始化构造函数-BeanService
Bean-init-method
Bean-destroy-method




     @Scope

        限定的是@Bean的生命周期.以下是我在官方文档上摘录的,仅在需要的时候看一下即可.
        @Scope("singleton")        默认的,为单例
        @Scope("prototype")        多例
        @RequestScope                Web项目中给每个request单独建立一个实例
        @SessionScope                 Web项目中给每个session单独建立一个实例
        @ApplicationScope           Web项目中给每个ServerContext单独创建一个实例
        @WebSocketScope           Web项目中给每个WebSocket单独创建一个实例

     实战

        在看汪云飞著写的《springboot实战》时,尝试的敲其中的demo,当我在敲@Configuration和@Bean的时候却报错了,我的代码如下:

方法类:

package com.yczuoxin.demo.code;

public class FunctionService {

    public String sayHello(String word){
        return "Hello " + word + " !";
    }
}

使用方法类:

package com.yczuoxin.demo.code;

public class UserFunctionService {

    FunctionService functionService;

    public void setFunctionService(FunctionService functionService){
        this.functionService = functionService;
    }

    public String SayHello(String word){
        return functionService.sayHello(word);
    }
}

配置类:

package com.yczuoxin.demo.code;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JavaConfig {

    @Bean
    public FunctionService functionService(){
        return new FunctionService();
    }

    @Bean
    public UserFunctionService userFunctionService(){
        UserFunctionService userFunctionService = new UserFunctionService();
        userFunctionService.setFunctionService(functionService());
        return userFunctionService;
    }

    @Bean
    public UserFunctionService userfunctionService(FunctionService functionService){
        UserFunctionService userFunctionService = new UserFunctionService();
        userFunctionService.setFunctionService(functionService);
        return userFunctionService;
    }
}

测试类:

package com.yczuoxin.demo.code;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
        UserFunctionService userFunctionService = context.getBean(UserFunctionService.class);
        System.out.println(userFunctionService.SayHello("java Config"));
    }
}

        当时的我一脸懵逼,怎么回事?看了下报错,报错信息为:

No qualifying bean of type 'com.yczuoxin.demo.code.UserFunctionService' available: expected single matching bean but found 2:
userFunctionService,userfunctionService

        仔细一看,原来我有一个方法名字写错了.于是我调用context.getBeanDefinitonNames()获取所有的声明的bean发现结果有四个是我创建的:

        javaConfig,functionService,userFunctionService和userfunctionService.

    在调用context.getBeanNameForType(UserFunctionService.class),获取的是两个值:userFunctionService和userfunctionService.

        spring的启动顺序为:首先会去configuration里面去找到所有的bean并且注册到IoC容器中,然后找到对应的bean去调用方法.所以问题就出在当我使用getBean是用type去寻找的,结果spring去找对应的bean的时候发现有两个bean,spring不知道用哪个bean来调用方法,所以抛出了异常.



猜你喜欢

转载自blog.csdn.net/ycxzuoxin/article/details/80872627