1、理论分析
Spring Boot实现依赖注入,主要需要三组注解:
1、实例注册:
用来定义需要被Spring Boot管理Bean。这些注解主要包括:@Component
,@Service,@Repository,@Controller等。@Service用来定义业务层的实例,@Controller定义控制层的实例,@Repository定义持久层的实例,而对于分层不明的,一般使用@Component来定义。
2、实例扫描:
用来扫描托付给Spring Boot管理的Bean。在Spring Boot,可以通过两种方式来开启实例扫描:
1)@SpringBootApplication:这个注解一般给启动类使用,其中封装了很多重要的注解,包括@EnableAutoConfiguration、@ComponentScan以及@Configuration。其中,@EnableAutoConfiguration用来开启自动配置,@ComponentScan用来启动实例扫描。通过给启动类标注@SpringBootApplication注解,可以启动实例扫描。
2)@EnableAutoConfiguration + @ComponentScan:对于不想使用@SpringBootApplication其他功能的情况下,可以只使用这两个注解来实现实例扫描。
需要注意的是,@ComponentScan只扫描当前类所在的包,以及子包中的类。@SpringBootApplication的注解扫描是通过@ComponentScan来实现的,所以同样如此。
3、依赖注入:
Bean已经注册了,也被扫描了,接下来就可以使用了。Spring Boot中使用依赖注入,可以通过给属性标注@Autowired和@实现。
@Autowired:在Spring Boot应用启动时,Spring容器会自动装载AutowiredAnnotationBeanPostProcessor来扫描@Autowired注解,并为扫描到添加了注解的属性注入相应的Bean。
@Qualifier:用来指定需要被注入的Bean的名称。默认情况,Spring Boot通过类型来装载实例,但是在一些情况下,例如装载某个接口类型的实例,但是该接口有两个以上的实现类都注册给了Spring Boot去管理Bean,这时候如果通过类型去装载实例,Spring Boot无法判断去装载哪个实例,就会抛出异常。所以,这时候应该在注册实例的时候指定实例的名称,然后在装载的时候通过@Qualifier指定装载的实例名。
2、代码实战
启动类:
package com.be;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
/**
* Created by <nanzhang, nan.zhang@mobvoi.com> on 2019/01/29.
*/
@ServletComponentScan
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
定义了一个Counter类,通过@Component注册给Spring Boot管理实例:
package com.be.component;
import org.springframework.stereotype.Component;
/**
* Created by <nanzhang, nan.zhang@mobvoi.com> on 2019/02/01.
*/
@Component
public class Counter {
private int counter = 0;
public void increase() {
counter++;
}
public int count() {
return counter;
}
}
注册了一个servlet,用来响应http请求。在servlet中,通过@Autowired获取了Counter的实例:
package com.be.servlet;
import com.be.component.Counter;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Created by <nanzhang, nan.zhang@mobvoi.com> on 2019/01/22.
*/
@WebServlet(urlPatterns = "/count")
public class FallbackServlet extends HttpServlet {
@Autowired
private Counter counter;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
request.setCharacterEncoding("UTF8");
response.setContentType("application/json; charset=UTF-8");
response.setCharacterEncoding("UTF8");
counter.increase();
response.getWriter().print("do response, counter: " + counter.count());
}
}
注意,Spring Boot的默认启动端口是8080。打开浏览器,输入localhost:8080/count,能看到返回结果,说明Counter的实例自动注入成功。