由David发表在天码营
我们已经了解了依赖注入的基本原理,初识了@Component
和@AutoWired
标注的用法。为一个应用中的Beans的配置依赖注入关系的过程称之为装配(Wiring)。
Spring提供三种装配方式:
之前的示例就是使用自动装配。通过给Java类增加相应的标注,就能够启用Spring隐式的Bean发现机制,并自动完成装配过程。我们在开发中应该尽可能使用自动装配,足以应付开发中的绝大多数情况。
Spring通过两个特性实现自动装配:
@Autowired
标注:自动建立Spring Beans之间的依赖关系在某些情况下,基于XML配置和基于Java配置的显式装配会有用武之地,比如实例化一个第三方库中的Bean。这种情况下,Java配置和XML配置我们优先使用Java配置,因为这是一种类型安全的方式,能够在编译时就尽早发现错误。
我们先来了解自动装配吧!
如何启动自动扫描机制呢? 在Spring Boot应用中,加入@SpringBootApplication
标注就能启动自动扫描。
package com.tianmaying;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
我们也可以通过XML配置或者Java配置的方式来启动自动扫描。
XML配置方式
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.tianmaying" />
beans>
标签将会开启Spring Beans的自动扫描,并可设置base-package属性,表示Spring将会扫描该目录以及子目录下所有被@Component
标注修饰的类,对它们进行装配。
Java配置方式
package com.tianmaying.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.tianmaying")
public class BlogSystemConfig {
}
@Configuration
表示这个Java文件是一个配置文件,这类Java代码的作用在于配置,要和普通的Java代码区分开发,因此一般我们需要将其放在一个专门的包中,在代码例子中是com.tianmaying.config
。
@ComponentScan
表示开启Spring Beans扫描,类似于XML配置,这里也可以可以设置basePackages
属性。
这种字符串形式的表示虽然可以,但是不具备“类型安全”,因此Spring也提供了更加类型安全的机制,即通过类或者接口来设置扫描机制的目标目录。通过这种设置,会将类A
和类B
所在的目录作为扫描的目标目录。
类型安全大家可以这样理解:
如果使用字符串的形式,即使类名写错了,在开发时是发现不了的,会在运行时抛出异常。
而使用Java类的形式,类名写错的话,编译时就会提示错误,比如Eclipse中就会提示找不到类的错误信息,这就避免了这种情况下的运行时异常,因此是更加安全的。
@Component
用于定义一个Spring Bean。启动了自动扫描后,被@Component
标注的类都自动会注册为Spring Beans。比如,我们可以将UserDao
和PostDao
注册为Spring Beans:
@Component
public class UserDao {
...
}
@Component
public class PostDao {
@Autowired
private UserDao userDao;
...
}
在Spring上下文中,每个Bean都有自己的ID。Spring扫描过程中所创建的Bean都有默认的ID,这个ID为将类名首字母小写形成的字符串。
如果我们希望给某个类对应的Bean取特点的名字,则可以给@Component
标注传入指定的参数,比如:
@Component("customizedName")
public class UserDao {
...
}
@Autowired
标注可以作用在以下四种地方
通常情况下,我们通过给成员变量加@Autowired
标注就能满足开发中的大部分场景。
回到博客应用中,我们已经为PostDao
和UserDao
增加标注@Component
,这样就能注册为Spring Bean,被`Service`类所使用。
同样,PostService
和UserService
也可以用@Component
进行标注,通过在私有属性上添加@Autowired
标注,将其所依赖的Dao类注入其中。
@Component
public class PostService {
@Autowired
private PostDao postDao;
...
}
@Component
public class UserService {
@Autowired
private UserDao userDao;
...
}
最后在Servlet中,可以注入Service,比如IndexController
类中:
@WebServlet("")
public class IndexController extends HttpServlet {
@Autowired
private UserService userService;
...
}
使用自动装配时,如果在应用上下文中,对应类型的Bean有且只有一个,则会自动装配到该属性上。
如果没有找到对应的Bean,应用会抛出对应的异常,如果想避免抛出这个异常,则需要设置@Autowired(required=false)
。
这个属性应当谨慎使用,我们可能需要处理NullPointerException
的问题。
更多文章请访问天码营网站