一、Spring 注解版 IOC
1、注解版 IOC 概述
Spring不但可以通过配置文件来创建对象进行依赖注入也可以通过注解的方式来完成,在企业中这两种方式通常是一起使用的,对于我们自己定义的类,我们可以使用注解来创建对象和依赖注入,但是如果是其他第三方的类,我们无法在这些类上面添加注解,那就只能通过配置的方式来配置了。
2、常用注解
- @Component:该注解需要定义在类上,表示该类对象需要通过 Spring 来创建,@Component 是一个通用的注解,在每一层都可以使用。
- @Controller:该注解需要定义在控制层的类上,表示该类对象需要通过 Spring 来创建,@Controller 层是 spring mvc 的注解,具有将请求进行转发,重定向的功能。
- @Service:该注解需要定义在业务层的类上,表示该类对象需要通过 Spring 来创建,这个注解只是标注该类处于业务逻辑层,即带有额外标识的公共,表明这是业务逻辑层。
- @Repository:该注解需要定义在数据层的类上,表示该类对象需要通过 Spring 来创建,还注解还具有将数据库操作抛出的原生异常翻译转化为 Spring 的持久层异常的功能。
上述4个注解的作用等同于<bean>
标签,在使用这些注解时可以传入一个字符串作为 bean id,如果没有传入 bean id 则默认 bean id 等于类名首字母小写。
- @Autowired:该注解需要定义在类的属性之上,表示该属性的值需要由spring进行注入。
- @Resource:该注解需要定义在类的属性之上,表示该属性的值需要由spring进行注入。
上述两个注解用于进行依赖注入,只不过 @Autowired 优先按属性类型自动注入,而 @Resource 优先按属性名称自动注入。
@Resource 有两个属性是比较重要的,分是 name 和 type,Spring 将 @Resource 注解的 name 属性作为 bean id 去容器中查找,而 type 属性则解析为 bean 的类型。所以如果使用 name 属性,则优先通过属性名称自动注入,而使用 type 属性时则使用类型匹配自动注入策略。如果既不指定 name 也不指定 type 属性,这时将通过优先用过属性名称自动注入策略。无论使用 @Resource 还是 @AutoWired 如果匹配策略是按照类型匹配,这时 Spring 容器中有超过1个相同类型对象时,就会出现异常。
最后,如果使用了注解的方式,那么需要在 applicationContext.xml 中声明添加了注解的这些类所在的包名,这样 Spring 才能去扫描这些包,如果不配置注解将不生效。配置方式如下:
<context:component-scan base-package="com.spring.demo2"></context:component-scan>
注意:使用Spring时,通过注解和通过配置文件创建的对象都保存在了Spring容器中,所以既可以使用注解的方式来完成依赖注入,也可以使用<property>
标签进行注入。换句话讲,我们在配置文件中通过<bean>
标签创建的对象,可以使用注解的方式来注入,使用注解的方式创建的对象也可以使用<property>
标签来注入。
3、注解版 IOC 示例
(1)service 层
@Service
public class UserService {
@Resource
private UserDao userDao;
public void select() {
System.out.println("正在执行查询业务");
userDao.select();
}
}
(2)dao层
@Repository
public class UserDao {
@Resource
private DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void select() {
System.out.println("执行新增数据");
Connection conn = null;
PreparedStatement ps = null;
try {
conn = dataSource.getConnection();
String sql = "select * from products";
ps = conn.prepareStatement(sql);
ResultSet resultSet = ps.executeQuery();
while(resultSet.next()) {
System.out.println(resultSet.getInt("p_id") + "\t" +
resultSet.getString("p_name") + "\t" +
resultSet.getDouble("p_price") + "\t" +
resultSet.getInt("p_count") + "\t" +
resultSet.getString("p_class") + "\t" +
resultSet.getString("p_attribute"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
(3)applicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<context:component-scan base-package="com.spring.demo2"></context:component-scan>
<!-- 创建连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--提供数据库连接信息和连接池的常用信息-->
<!--驱动类-->
<property name="driverClass" value="${jdbc.driverClass}" />
<!--连接数据库的地址-->
<property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
<!--连接数据库的用户名-->
<property name="user" value="${jdbc.user}" />
<!--连接数据库的密码-->
<property name="password" value="${jdbc.password}" />
<!--最大连接数-->
<property name="maxPoolSize" value="${c3p0.maxPoolSize}"></property>
<!--最小连接数-->
<property name="minPoolSize" value="${c3p0.minPoolSize}"></property>
<!--初始化连接数-->
<property name="initialPoolSize" value="${c3p0.initialPoolSize}"></property>
<!--自增长连接数-->
<property name="acquireIncrement" value="${c3p0.acquireIncrement}"></property>
<!--连接对象空闲时间 超出10分钟销毁-->
<property name="maxIdleTime" value="${c3p0.maxIdleTime}"></property>
<!--连接数据库的等待时间 超出等待时间 抛出异常-->
<property name="checkoutTimeout" value="${c3p0.checkoutTimeout}"></property>
<!--检查连接的间隔时间-->
<property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}"></property>
</bean>
<!-- 创建资源文件加载器对象 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:c3p0.properties"></property>
</bean>
</beans>
(4)测试类:Action类
public class UserAction{
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("spring2.xml");
UserService service = (UserService) ac.getBean("userService");
service.select();
}
}