Spring Framework 基础 —— 第六章 Spring 注解开发
1. Spring 原始注解
Spring 是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替 XML 配置文件可以简化配置,提高开发效率。
Spring 的原始注解主要是替代 <bean>
标签的配置
注解 | 说明 |
---|---|
@Component |
使用在类上用于实例化 Bean |
@Controller |
使用在 Web 层上用于实例化 Bean |
@Service |
使用在 Service 层上用于实例化 Bean |
@Repository |
使用在 Dao 层上用于实例化 Bean |
@Autowired |
使用在字段上用于根据类型依赖注入 |
@Qualifier |
结合 @Autowired 一起使用用于根据名称进行依赖注入 |
@Resource |
相当于 @Autowired + @Qualifier ,按照名称进行依赖注入(需要 javax.annotation 依赖) |
@Value |
注入普通属性 |
@Scope |
标注 Bean 的作用范围 |
@PostConstruct |
使用在方法上标注该方法是 Bean 的初始化方法 |
@PreDestroy |
使用在方法上标注该方法是 Bean 的销毁方法 |
注意⚠️:
在使用注解开发的时候,需要在 applicationContext.xml
中配置组件扫描,作用是指定哪个包及其子包下的 Bean 需要进行扫描以便识别使用注解配置的类、字段和方法,否则会出现 NoSuchBeanDefinitionException
错误。
<!-- Configure component scan -->
<context:component-scan base-package="com.gregperlinli"></context:component-scan>
示例代码:
com.yourname.dao.UserDao
public interface UserDao {
public void save();
}
com.yourname.dao.impl.UserDaoImpl
import com.gregperlinli.dao.UserDao;
import org.springframework.stereotype.Repository;
/**
* <bean id="userDao" class="com.gregperlinli.dao.impl.UserDaoImpl"></bean>
*/
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("Save running ...");
}
}
com.yourname.service.UserService
public interface UserService {
public void save();
}
com.yourname.service.impl.UserServiceImpl
import com.gregperlinli.dao.UserDao;
import com.gregperlinli.service.UserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* <bean id="userService" class="com.gregperlinli.service.impl.UserServiceImpl"></bean>
*/
@Service("userService")
@Scope("singleton")
public class UserServiceImpl implements UserService {
@Value("${jdbc.driver}")
private String driver;
// <property name="userDao" ref="userDao"/>
// @Autowired // Matching from Spring container by data type
// @Qualifier("userDao") // Match from the container according to the ID value, but here @Qualifier should be used in combination with @Autowired
@Resource(name="userDao") // @Resource is equivalent to @Qualifier + @Autowired
private UserDao userDao;
@Override
public void save() {
System.out.println(driver);
userDao.save();
}
@PostConstruct
public void init() {
System.out.println("Service object initialize ...");
}
@PreDestroy
public void destroy() {
System.out.println("Service object destroy ...");
}
}
com.yourname.web.UserController
import com.gregperlinli.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = app.getBean(UserService.class);
userService.save();
app.close();
}
}
applicationContext.xml
<?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 http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Load external properties file -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- Configure component scan -->
<context:component-scan base-package="com.gregperlinli"/>
</beans>
2. Spring 新注解
使用上面额度注解还不能完全替代 XML 配置文件,还需要使用注解替代的配置如下:
非自定义的 Bean 的配置:
<bean>
加载 Properties 文件的配置:
<context:property-placeholder>
组件扫描的配置:
<context:component-scan>
引入其他文件:
<import>
Spring 的新注解:
注解 | 说明 |
---|---|
@Configuration |
用于指定当前类是一个 Spring 配置类,当创建容器的时候会从该类上加载注解 |
@ComponentScan |
用于指定 Spring在初始化容器是要扫描的包。作用和在 Spring 的 XML 配置文件中的 <context:component-scan base-package="com.yourname"/> 一样 |
@Bean |
使用在方法上,标注将该方法返回的值存储到 Spring 容器中 |
@PropertySource |
用于加载 .properties 文件中的配置 |
@Import |
用于导入其他配置类 |
示例代码:
com.yourname.config.SpringConfiguration
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration // This flag is the core configuration class of spring
@ComponentScan("com.gregperlinli") // <context:component-scan base-package="com.gregperlinli"/>
@Import(DataSourceConfiguration.class) // <import resource=""/>
public class SpringConfiguration {
}
com.yourname.config.DataSourceConfiguration
import com.mchange.v2.c3p0.ComboPooledDataSource;
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") // <context:property-placeholder location="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("dataSource") // Spring stores the return value of the current method in the Spring container with the specified name
public DataSource getDataSource() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
}
}
com.yourname.web.UserController
import com.gregperlinli.config.SpringConfiguration;
import com.gregperlinli.service.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class UserController {
public static void main(String[] args) {
// ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
UserService userService = app.getBean(UserService.class);
userService.save();
app.close();
}
}