1. 通过注解实现自动装配
在Spring使用注解之前首先要开户注解的自动扫描功能
修改Spring的xml配置文件:
<!--设置扫描位置,自动扫描该包下的注解-->
<context:component-scan base-package="com.XXX">
</context:component-scan>
① @Autowired注解
@Autowired为Spring提供的注解,只按照byType注入,需要导入包org.springframework.beans.factory.annotation.Autowired;
在默认情况下使用 @Autowired 注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出 BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean。
当不能确定 Spring 容器中一定拥有某个类的 Bean 时,可以在需要自动注入该类 Bean 的地方可以使用@Autowired(required= false)。这等于告诉 Spring:在找不到匹配 Bean 时也不报错。
@Autowired可以写在字段和setter方法上。如果写在字段上,那么就不需要再写setter方法
② @Qualifier注解
当ioc容器根据属性类型去容器中找找到多个相同类型的组件,再将属性的名称作为组件(bean)的id去容器中查找找不到时就是用这两个注解搭配,指定需要装配的bean的id。
@Qualifier注解可以和使用Autowired搭配使用
@Qualifier指定需要装配的组件的id,而不是使用属性名。
例如下边例子,spring就会优先在容器中查找id为“cat”的组件。
public class Peopel {
@Autowired
@Qualifier(value = "cat")
private Cat cat;
}
③ Resource注解
@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。
@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。
@Resource可以写在字段和setter方法上。如果写在字段上,那么就不需要再写setter方法
@Resource装配顺序:
(1)如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
(2)如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
(3)如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
(4)如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。
2. 常用注解组件
- @Component:通用注解,可标注任意类为
Spring
组件。如果一个 Bean 不知道属于哪个层,可以使用@Component
注解标注。 -
@Repository:用于声明DAO层的
-
@Service:用于业务层
-
@Controller:用于控制器
3. 使用配置类开启注解配置
java config是指基于java配置的spring。传统的Spring一般都是基本xml配置的,后来spring3.0新增了许多java config的注解。
注解 | 说明 |
---|---|
@Configuration | 在类上打上这一标签,表示这个类是配置类 |
@ComponentScan | 相当于xml的<context:componentscan basepakage=> |
@Bean | bean的定义,相当于xml的<bean id="objectMapper" class="org.it.map.ObjectMapper" /> |
@EnableWebMvc | 相当于xml的<mvc:annotation-driven> ,springMVC阶段涉及 |
@ImportResource | 相当于xml的 <import resource="applicationContext-cache.xml"> |
@PropertySource | spring 3.1开始引入,它是基于java config的注解,用于读取properties文件 |
@Profile | spring3.1开始引入,一般用于多环境配置,激活时可用@ActiveProfiles注解,@ActiveProfiles("dev") |
基于JavaConfig的配置方式
表达形式层面
@Configuration
public class MockConfiguration{
//bean定义
}
注册bean定义层面
@Configuration
public class MockConfiguration{
@Bean
public MockService mockService(){
return new MockServiceImpl();
}
}
表达依赖注入关系层面
@Configuration
public class MockConfiguration{
@Bean
public MockService mockService(){
return new MockServiceImpl(dependencyService());
}
@Bean
public DependencyService dependencyService(){
return new DependencyServiceImpl();
}
}
4. @Value注解
- ${ property : default_value }——读取外部配置文件对应的property
- #{ obj.property? :default_value }——SpEL表达式对应的内容
创建MyDataSource类来读取jdbc.properties配置文件中信息
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
@Data
public class MyDataSource {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
}
创建一个配置类
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class MyConfig {
@Bean
public MyDataSource myDataSource() {
return new MyDataSource();
}
}
修改MyConfig类,#{ obj.property? :default_value }
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class MyConfig {
@Bean
public MyDataSource myDataSource() {
return new MyDataSource();
}
@Value("#{myDataSource.driver}")
private String driver;
@Value("#{myDataSource.url}")
private String url;
@Value("#{myDataSource.username}")
private String username;
@Value("#{myDataSource.password}")
private String password;
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setUrl(url);
return dataSource;
}
}
接下来注释掉之前xml配置文件中的dataSource,再进一步优化java代码
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
@Configuration
//@PropertySource("classpath:jdbc.properties")//解析指定文件
public class MyConfig {
//@Value("${jdbc.url}")通过springEL表达式(读取括号里面表达式的值)并且赋给下面的变量
@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 dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setUrl(url);
return dataSource;
}
}
以上代码中,把#{},改为${},直接读取properties文件中的内容。
也可以使用//@PropertySource("classpath:jdbc.properties")//解析指定文件properties文件
这就配置完成啦