spring框架:基于注解的IOC配置
本人小白一枚,欢迎大家一起讨论学习,如有错误,还望大家指教。
基于注解的IOC配置
前面学习了基于xml方式的IOC的配置,现在我们要学习基于注解放方式的IOC配置,首先我们要在脑海中有一个认知,就是无论是注解配置还是xml配置的功能都是一样的,都是为我们降低程序间的耦合,只是实现的形式不一样。我们同样使用上一篇的案例,模拟三层模式的开发。
- 常见maven工程,在pom文件中添加spring的坐标,这里的版本我使用的是5.0.2。
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
- 创建spring的核心配置文件,对于这个文件的名称,我们暂时可以自己命名,因为我们是通过自己手动加载的方式,在配置文件中添加注解要扫描的包。
<context:component-scan base-package="controller, dao, service"></context:component-scan>
- 创建持久层dao,并添加接口以及实现类。
public interface AccountDao {
void saveAccount();
}
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
public void saveAccount() {
System.out.println("对象保存了");
}
}
- 创建业务层service,并添加接口以及实现类。
public interface AccountService {
void saveAccount();
}
@Service("accountService")
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao dao;
public void saveAccount() {
dao.saveAccount();
}
}
- 创建控制层controller,并添加测试方法以及查看测试结果。
public class AccountDemo {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
AccountServiceImpl accountService = context.getBean("accountService", AccountServiceImpl.class);
accountService.saveAccount();
}
}
项目结构图:
总结: 上面已经使用注解简单演示了一下,这里要总结下常用的注解以及它们的含义。
用于创建对象的注解:相当于xml中<bean id="" class="">
-
@Component
:让spring帮我们创建对象,相当于xml中配置的bean标签,所具有的属性。-
value
:指定bean的id。如果不指定value属性,默认bean的id是当前类的类名的首字母小写。
-
-
@Contrller
、@Service
、@Repository
:这三个注解都是@Component的衍生注解,它们的作用及属性都是一样的,只不过是提供了更加明确的语义化,使我们的三层对象更加清晰。-
@Controller
:一般用于表现层的注解。 -
@Service
:一般用于业务层的注解。 -
@Repository
:一般用于持久层的注解。
-
用于注入数据的注解:相当于xml中<property name="" ref=""> <property name="" value="">
-
@AutoWired
:自动按照类型注入,只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配时,就可以注入成功。如果ioc容器没有匹配的类型,则会报错。如果ioc容器中有多个类型匹配时,咋们可以配合使用@Qualifier
用该注解指定对应的id即可。注意:使用注解注入类型时,set方法可以省略,它是通过暴力反射的方式进行依赖注入的。该注解可以对成员变量、构造方法、方法进行标注,来完成自动装配工作,如果方法有参数,会在IOC容器中自动寻找同类型参数为其赋值。-
required
:默认情况下依赖对象必须存在,如果要允许null,可以设置该属性为false,也就是说默认是为true。
-
-
@Qualifier
:在自动类型注入的基础上,在按照Bean的id注入,再给字段注入时不能独立使用,必须和@Autowired
一起使用,但是给方法参数进行注入时,可以独立使用。-
value
:指定bean的id。
-
-
@Resource
: 按照Bean的id注入,同样只能注入bean类型。-
name
:指定bean的id。
-
-
@Value
:用于注入基本数据类型和String类型数据的-
value
:用于指定要注入的值。
-
用于改变作用范围的:相当于<bean id="" class="" scope="">
-
@Scope
:指定bean的作用范围。-
value
:指定范围的值,取值有singleton
、prototype
、request
、session
、globalsession
。
-
和生命周期相关的:相当于 <bean id="" class="" init-method="" destroy-method="" />
-
@PostConstruct
:用于指定初始化方法的。 -
@PreDestroy
:用于指定销毁方法的。
疑问: 在介绍注解@Resource
时,我想到如果不写name
属性会怎么,它会怎么我们注入依赖呢?所以要在这里详细记录下@Autowired
和@Resource
的区别。@Autowired
注解是spring自己定义的,但spring同样支持几个有由JSR-250规范定义的注解,它们分别是@Resource
、@PostConstruct
以及@PreDestroy
。@Resource
的作用相当于@Autowired
,只不过@Autowired
按byType自动注入,而@Resource
默认按 byName自动注入罢了。@Resource
有两个属性是比较重要的,分是name
和type
,Spring
将@Resource
注解的name
属性解析为bean的名字,而type
属性则解析为bean的类型。所以如果使用name
属性,则使用byName的自动注入策略,而使用type
属性时则使用byType自动注入策略。如果既不指定name
也不指定type属性,这时将通过反射机制使用byName自动注入策略。
@Resource
装配顺序
1. 如果同时指定了name
和type
,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2. 如果指定了name
,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type
,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name
,又没有指定type
,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
Spring注解和Xml的对比:
- 注解的优势:配质简单,维护方法。
- XML的优势:不用改源码,不涉及重新编译和部署。
Spring的纯注解配置
通过上面的阐述,基于注解的IOC配置已经完成,但是我们依然离不开spring的xml配置文件,我们能不能不写bean.xml而全部使用注解来实现呢,结果是当然可以,我们简单说明下一下这些注解。
-
@Configuration
:该注解指定当前类是一个spring配置类,当创建容器时,会从该类上加载注解。在获取容器时需要使用AnnotationApplicationContext(有@Configuration 注解的类.class)。-
value
:用来指定配置类的字节码。
-
-
@ComponentScan
:用于指定spring在初始化容器时要扫描的包,作用和在spring的xml配置文件中的<context:component-scan base-package="包的路径"/>
是一样的。-
basePackages
:用于指定扫描的包,和该注解的value属性作用是一样的。
-
-
@Bean
:该注解只能写在方法上,表明使用此方法创建一个对象,并且注入到spring的容器中。-
name
:给当前@Bean注解方法创建的对象指定一个名称(即bean的id)。
-
-
@PropertySouorce
: 用于加载.properties文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到properties配置文件中,就可以使用此注解指定properties配置文件的位置。-
value[]
:用于指定properties文件位置,如果是在类路径下,需要写上classpath。
-
-
@Import
:用于导入其他配置类,在引入其他配置类时,可以不用在写@Configuration 注解。当然写上也没问题。-
value[]
:用于指定其他配置类的字节码。
-