我们在前面向读者介绍了Spring的配置文件,可以在配置文件中声明Bean,把对象的创建权交给Spring容器,并且实际演示了如何配置一个经典的Bean——数据源的配置。经过实际的上手我们会发现:xml的配置显得有些繁重,于是更便捷的配置方式便应运而生了——注解开发。
Spring框架有4个原生注解用于声明需要放至于IoC容器中,分别是@Controller,@Service,@Repository,@Component。他们没有实际的区别,仅在于后续划分代码结构时,各个分层上一般使用不同的注解。
import com.bylearning.spring.dao.UserDao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoImpl implements UserDao {
@Override
public void saveUser() {
System.out.println("save successfully");
}
}
Spring框架也提供了3个原生注解:@Autowired,@Resource,@Qualifier。@Autowired是用于按照类型(byType)装配依赖对象。默认情况下,它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果想要使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。@Resource注解默认按照名称进行装配。名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。@Qualifier注解用于解决歧义性问题,当有多个相同类型的Bean时,可以使用该注解指定要注入的Bean。
总结来说,@Autowired主要用于按照类型装配依赖对象,可以结合@Qualifier注解使用;@Resource默认按照名称装配依赖对象,可以指定name属性进行配置;@Qualifier用于解决歧义性问题,指定要注入的Bean。
import com.bylearning.spring.dao.UserDao;
import com.bylearning.spring.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier(value = "userDaoImpl")
private UserDao userDao;
@Override
public void saveUser() {
userDao.saveUser();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<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 https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.bylearning.spring" />
</beans>
?我们拥有了上面的3个注解后,似乎可以将大部分的xml配置转化为注解了,但是请读者思考有哪些情景依靠这3个注解无法注解化呢?下面给出了场景与对应的解决办法:
在以下例子中,主配置文件借助@Configuration注解将类声明为配置类,并用@ComponentScan注解对包进行扫描,将该包下的类(含有@Component等声明为Spring组件的注解)添加进IoC容器,借助@Import注解引入了另一个配置文件——数据源配置文件,在数据源配置文件中,利用@PropertySource注解引入了一个Properties文件,利用@Bean注解注册了一个Druid数据源。
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@ComponentScan("com.bylearning.spring")
@Import({DataSourceConfiguration.class})
public class SpringConfiguration {
}
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource getDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
掌握了这些注解后,可以大大减轻xml配置的繁重工作了。我们可以再回顾一下在引子中提到的Spring的配置开发(附链接),对比一下将更能发现注解开发的便捷性。