1. 常用注解
我们上篇博文介绍了基于XML的IOC配置,可以发现该种方式每次只要有bean让Spring管理,都需要在配置文件中添加相应的配置,当bean过多时就会显得配置文件过于臃肿,不便于维护,所以现在我们来介绍一下基于注解的IOC配置。需要注意的是,基于注解的IOC配置,与在xml中配置目的是一样的,都是降低代码之间的耦合度的,只是配置的形式不一样。
1.1 用于创建对象的
-
@Component:在类上面使用该注解,把资源让Spring来管理,相当于在xml中配置了一个bean。
属性:value:指定bean的id,如果不指定value属性,默认bean的id是当前类的类名,首字母小写。
// 单独配置 value时,可以省略 value属性名称 @Component(value = "accountDao") public class AccountDaoImpl implements IAccountDao { }
-
@Controller:一般用于表现层的注解。用法与@Component相同。
-
@Service:一般用于业务层的注解。用法与@Component相同。
-
@Repository:一般用于持久层的注解。用法与@Component相同。
1.2 用于注入数据的
-
@Autowired:自动按类型注入,当使用注解注入属性时,set方法可以省略。它只能注入其他bean类型。在使用@Autowired时,首先在容器中查询对应类型的bean,如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据。如果查询的结果不止一个,那么@Autowired会根据名称来查找。如果查询的结果为空,那么会抛出异常。
@Repository("accountDao") public class AccountDaoImpl implements IAccountDao { } @Service("accountService") public class AccountServiceImpl implements IAccountService { @Autowired private IAccountDao accountDao; }
-
@Qualifier:在自动按照类型注入的基础之上,再按照bean的id注入。它在给字段注入时不能独立使用,必须和@Autowire一起使用,但是给方法参数注入时,可以独立使用。
属性:value:指定bean的id。
@Repository("accountDao1") public class AccountDaoImpl1 implements IAccountDao { } @Repository("accountDao2") public class AccountDaoImpl2 implements IAccountDao { } @Service("accountService") public class AccountServiceImpl implements IAccountService { @Autowired @Qualifier("accountDao2") //如果不使用 @Qualifier指定注入 bean的 id为 accountDao2,那么这里注入的将会是 accountDao1 private IAccountDao accountDao1; }
-
@Resource:直接按照Bean的id注入,它也只能注入其他bean类型。
属性:name:指定bean的id。
@Repository("accountDao") public class AccountDaoImpl implements IAccountDao { } @Service("accountService") public class AccountServiceImpl implements IAccountService { @Resource(name = "accountDao") private IAccountDao accountDao; }
-
@Value:注入基本数据类型和String类型数据的。
属性:value:用于指定值。
@Service("accountService") public class AccountServiceImpl implements IAccountService { @Value("${user.name}") private String name; //从 properties文件中读取 user.name的值 }
1.3 用于改变作用范围的
-
@Scope:指定bean的作用范围。
属性:value:指定范围的值。取值:singleton、prototype、request、session、globalsession。
@Service("accountService") @Scope("prototype") public class AccountServiceImpl implements IAccountService { }
1.4 和生命周期相关的
-
@PostConstruct:指定某个方法为初始化方法。
-
@PreDestory:指定某个方法为销毁方法。
@PostConstruct public void init(){ System.out.println("初始化方法执行了"); } @PreDestroy public void destroy(){ System.out.println("销毁方法执行了"); }
2. 代替配置文件的注解
写到此处,基于注解的IOC配置已经完成,但是大家都发现了一个问题,我们依然离不开Spring的xml配置文件,那么能不能不写这个applicationContext.xml,所有配置都用注解来实现呢?我们发现,之所以我们现在离不开xml配置文件,是因为我们有一句很关键的配置:
<!-- 告知 spring框架在,读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中 -->
<context:component-scan base-package="com.joker"></context:component-scan>
如果他要也能用注解配置,那么我们就离脱离xml文件又进了一步。
-
@Configuration:用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解。获取容器时需要使用AnnotationApplicationContext类的方法。
@Configuration public class SpringConfiguration { }
-
@ComponentScan:用于指定spring在初始化容器时要扫描的包。作用和在Spring的xml配置文件中的<context:component-scan base-package=“com.joker” />是一样的。
属性:value:用于指定要扫描的包。和标签中的basePackages属性作用一样。
@Configuration @ComponentScan("com.joker") public class SpringConfiguration { }
-
@Bean:该注解只能写在方法上,将方法的返回值作为一个bean,并且放入spring容器。
属性:name:给当前@Bean注解方法创建的对象指定一个名称(即bean的id)。
@Bean(name = {"jdbcTemplate"}) public JdbcTemplate createJdbcTemplate(@Qualifier(value = "dataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } @Bean(name = {"dataSource"}) public DataSource createDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driverClassName); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; }
-
@PropertySource:用于加载properties文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到properties配置文件中,就可以使用此注解指定properties配置文件的位置。
属性:value[]:用于指定properties文件位置。如果是在类路径下,需要写上classpath:
@PropertySource(value = {"classpath:jdbc.properties"}) public class JdbcConfig { @Value(value = "${jdbc.driverClass}") private String driverClassName; @Value(value = "${jdbc.url}") private String url; @Value(value = "${jdbc.username}") private String username; @Value(value = "${jdbc.password}") private String password; @Bean(name = {"jdbcTemplate"}) public JdbcTemplate createJdbcTemplate(@Qualifier(value = "dataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } @Bean(name = {"dataSource"}) public DataSource createDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driverClassName); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } }
-
@Import:用于导入其他配置类,在引入其他配置类时,其他类上可以不用再写@Configuration注解。当然,写上也没问题。
属性:value[]:用于指定其他配置类的字节码。
@Configuration @ComponentScan("com.joker") @Import(value = {JdbcConfig.class}) public class SpringConfiguration { }
通过注解获取容器使用AnnotationConfigApplicationContext,如下所示:
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);