Spring原始注解
注解 | 说明 |
@Component | 使用在类上用于实例化Bean |
@Controller | 使用在类上用于实例化Bean(具有web层语义) |
@Service | 使用在类上用于实例化Bean(具有service层语义) |
@Repository | 使用在类上用于实例化Bean(具有dao层语义) |
@Autowired | 注入引用类型 |
@Qualifier | 注入引用类型 |
@Resource | 注入引用类型 |
@Value | 注入基本类型 |
@Scope | Bean作用范围配置 |
@PostConstruct | Bean生命周期配置(初始化时调用) |
@PreDestroy | Bean生命周期配置(被销毁时调用) |
配置组件扫描
在applicationContext.xml配置了组件扫描,就是告诉Spring去扫描该包及其子包下的注解
注意:配置组件扫描需要在context命名空间下进行,因此别忘了补上context命名空间(及其约束路径)
<!-- 配置组件扫描 -->
<context:component-scan base-package="service" />
<context:component-scan base-package="dao" />
@Component用于实例化Bean
@Component("userDao")
public class UserDaoImpl implements UserDao {
public void sayHi() {
System.out.println("Hello!!!");
}
}
@Controller/@Service/@Repository也用于实例化Bean,且带有语义
@Repository("userDao")
public class UserDaoImpl implements UserDao {
public void sayHi() {
System.out.println("Hello!!!");
}
}
@Autowired根据类名自动注入引用(如果该类在spring容器中拥有多个Bean,则报错)
@Component("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public void sayHi() {
userDao.sayHi();
}
}
@Autowired+@Qualifier根据id注入引用(两个配合使用,不能少写)
@Component("userService")
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier("userDao")
private UserDao userDao;
public void sayHi() {
userDao.sayHi();
}
}
@Resource根据id注入引用(完全等价于@Autowired+@Qualifier)
@Component("userService")
public class UserServiceImpl implements UserService {
@Resource(name = "userDao")
private UserDao userDao;
public void sayHi() {
userDao.sayHi();
}
}
@Value注入基本数据类型(通常与SPEL语法配合使用)
<!-- 在applicationContext.xml引入properties资源文件,就将这些键值对“倒入”了spring容器中 -->
<context:property-placeholder location="classpath:xxx.properties" />
@Component("userService")
public class UserServiceImpl implements UserService {
@Value("root")
private String username;
@Value("${password}")
private String password;
// ...
}
@Scope配置作用范围(singleton单例/prototype多例)
@Component("userDao")
@Scope("prototype")
public class UserDaoImpl implements UserDao {
// ...
}
@PostConstruct/@PreDestroy配置生命周期(初始化/销毁时自动调用的方法)
@Component("userDao")
public class UserDaoImpl implements UserDao {
@PostConstruct
public void init() {
System.out.println("初始化时调用我 >_<");
}
// ...
@PreDestroy
public void destroy() {
System.out.println("销毁时调用我 >_<");
}
}
Spring新注解
上面的经典注解,并不能完全取代xml配置文件。比如下列情况:
- 非自定义Bean(第三方直接提供的Bean):
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">...</bean>
- 加载资源文件:
<context:property-placeholder location="xxx.properties" />
- 配置组件扫描:
<context:component-scan base-package="xxx" />
- 分模块开发:
<import resource="applicationContext-xxx.xml" />
我们使用一些巧妙的思路和设计,解决上面的问题:
- 不再在applicationContext.xml中配置,而是将这些配置转移到config.SpringConfiguration.class类中
- applicationContext.xml中可以使用SPEL语法,但config.SpringConfiguration.class类中的java代码显然不可以使用。我们可以巧妙的解决这个问题——java代码不能用SPEL,但是注解可以使用SPEL;因此可以通过注解,将键值对信息注入给成员变量,我们就能间接使用到这些键值对信息了
- 最终,applicationContext.xml完全作废,
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
被替代为ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
注解 | 说明 |
@Configuration | 标明这是一个Spring配置类 |
@Bean | 被标注的返回值会直接被放到Spring容器中 |
@PropertySource | 用于加载资源文件 |
@ComponentScan | 用于配置组件扫描 |
@Import | 用于分模块开发 |
@Configuration // 表明这是一个配置类
@ComponentScan({"dao", "service"}) // 配置组件扫描
@PropertySource("classpath:jdbc.properties") // 加载资源文件
@Import({xxxConfiguration.class, xxxConfiguration.class}) // 分模块开发
public class SpringConfiguration {
@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("dataSource")
public DataSource getDataSource() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
}
}