Spring框架的作用和优点:
- spring是一个开源的轻量级的应用开发框架,其目的是用于简化企业级应用程序开发,减少侵入;
- spring提供的IoC 和AOP应用,可以将组建的耦合度降至最低,即解耦,便于系统日后维护和升级;
- spring为系统提供了一个整体解决方案,开发者可以利用它本身提供的功能外,也可以与第三方框架和技术整合,合一自由选择采用哪种技术进行开发。
Spring基础包
Spring-core-3.2.8.RELEASE.jar
Spring-context-3.2.8. RELEASE.jar
Spring-beans-3.2.8. RELEASE.jar
Common-logging.jar
Spring-expression-3.2.8. RELEASE.jar
- public class OracleUserDAO implements UserDAO{
- private JDBCDataSource dataSource;
- /** 创建 OracleUserDAO 对象必须依赖于JDBCDataSource实例 */
- public OracleUserDAO(JDBCDataSource dataSource) {
- this.dataSource = dataSource;
- }
- /** 根据唯一用户名查询系统用户, 如果没有找到用户信息返回null */
- public User findByName(String name) {
- System.out.println("利用JDBC技术查找User信息");
- String sql = "select id, name, pwd, phone from USERS where name=?";
- Connection conn = null;
- try {
- conn = dataSource.getConnection();
- PreparedStatement ps = conn.prepareStatement(sql);
- ps.setString(1, name);
- ResultSet rs = ps.executeQuery();
- User user=null;
- while(rs.next()){
- user = new User();
- user.setId(rs.getInt("id"));
- user.setName(rs.getString("name"));
- user.setPwd(rs.getString("pwd"));
- user.setPhone(rs.getString("phone"));
- }
- rs.close();
- ps.close();
- return user;
- } catch (SQLException e) {
- e.printStackTrace();
- throw new RuntimeException(e);
- }finally{
- dataSource.close(conn);
- }
- }
36.}
1. <!-- setter注入 -->
2.
3. <bean id="dataSource" class="org.tarena.dao.JDBCDataSource">
4.
5. <property name="driver" value="oracle.jdbc.OracleDriver"></property>
6.
7. <property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"></property>
8.
9. <property name="user" value="openlab"></property>
10.
11. <property name="pwd" value="open123"></property>
12.
13. </bean>
17. <!-- 构造器注入 -->
18.
19. <bean id="userDAO" class="org.tarena.dao.OracleUserDAO">
20.
21. <!-- 利用构造器参数注入bean的属性 -->
22.
23. <constructor-arg name="dataSource" ref="dataSource"/>
24.
25. </bean>
Spring IoC容器可以自动装配(autowire)相互协作bean之间的关联关系,autowire可以针对单个bean进行设置,autowire的方便之处在于减少xml的注入配置。
在xml配置文件中,可以在<bean/>元素中使用autowire属性指定自动装配规则,一共有五种类型值
No : 禁用自动装配,默认值
byName : 根据属性名自动装配。此选项将煎炒容器并根据名字查找与属性完全一致的bean
并将其与属性自动装配
byType : 如果容器中存在一个与指定属性类型相同的bean ,那么将与该属性自动装配
constructor : 与byType类似,不同之处在于它与构造器参数
autoDelete :
步骤八:测试引用方式集合注入
1.为Spring配置文件applicationContext.xml增加如下配置, 采用引用方式注入集合对象, 代码参考如下:
<!-- 定义集合Bean -->
<util:list id="oneList">
<value>Tom</value>
<value>Andy</value>
</util:list>
<util:set id="oneSet">
<value>James Gosling</value>
<value>Martin fowler</value>
</util:set>
<util:map id="oneMap">
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
</util:map>
<util:properties id="oneProps">
<prop key="username">root</prop>
<prop key="password">1234</prop>
</util:properties>
<!-- 引用方式注入集合属性 -->
<bean id="messagebean2" class="org.tarena.bean.MessageBean">
<property name="moduleName" value="资费管理"></property>
<property name="pageSize" value="5"></property>
<property name="username" value="andy"></property>
<property name="password" value="123"></property>
<!-- 引用方式注入集合属性 -->
<property name="someList" ref="oneList" />
<property name="someSet" ref="oneSet" />
<property name="someMap" ref="oneMap" />
<property name="someProps" ref="oneProps" />
</bean>
2. 增加Test2类测试如上配置, Test2代码如下:
package org.tarena.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.tarena.bean.MessageBean;
/** 引用方式注入集合 */
public class Test2 {
public static void main(String[] args) throws Exception{
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
MessageBean bean = ac.getBean("messagebean2",MessageBean.class);
bean.execute();
}
}
利用Spring表达式注入属性值
在工程的src下 ,创建属性文件db.properties , 文件内容如下
user=scott
password注入的值为null
修改applicationContext.xml文件,注入Spring表达式,代码如下
<util:properties id=”jdbcProperties” location=”classpath:db.properties” />
<bean id=”messagebean” class=”org.tarena.bean.MessageBean>
<property name=”moduleName” name=”资源管理”></property>
<property name=”pageSize” value=”5”></property>
<property name=”username” value=”#{jdbcProperties.user}”></property>
<property name=”password” ></property>
</bean>
测试Spring自动组建扫描
如何使用组件扫描的方式和"注解标记"配合获取容器中的ExampleBean对象
方案:
使用组建扫描,首先需要在XML配置中指定扫描类路径,配置代码如下
<context:component-scan base-package=”com.tarena”/>
上述配置,容器实例化时会自动扫描com.tarena包及其子包下的所有组件类。
指定扫描类路径后,并不是该路径下所有组件类都扫描到Spring容器的,只有在组件类定义前面有以下注解标记时,才会扫描到Spring容器
@Component 通用注解
@Name 通用注解
@Respository 持久化层组件注解
@Service 业务层组件注解
@Controller 控制层组件注解
3.1 问题
使用组件扫描的方式,重构如何控制ExampleBean实例化为单例或非单例模式。
3.2 方案
1. 通常受Spring管理的组件,默认的作用域是"singleton"。如果需要其他的作用域可以使用@Scope注解,只要在注解中提供作用域的名称即可
@Scope(“singleton”)
2.@PostConstruct 和 @PreDestroy注解分别用于指定初始化和销毁回调方法
4.2 方案
使用Spring注解方式实现组件的声明, 并且利用注解注入方式解决依赖关系.
Jar包如下
包含Spring必须的5个jar包, 以及数据库驱动程序
Spring-core-3.2.8.RELEASE.jar
Spring-context-3.2.8. RELEASE.jar
Spring-beans-3.2.8. RELEASE.jar
Common-logging.jar
Spring-expression-3.2.8. RELEASE.jar
Javax.inject-1.jar 是srping3.0开始增添的对JSR-330标准的支持,使用@Inject注解标记需要添加此jar包
Mysql-connector-java-5.1.8.bin.jar
Ojdbc5.jar
步骤八:使用注解将OracleUserDao声明为Bean, 并且注入到UserService中
1. 新建OracleUserDao实现UserDao接口,在该类中实现findByName方法, findByName方法调用JdbcDataSource的getConnection方法获取数据库连接. 使用注解@Repository将Oracle声明为存储组件, 并且设置组件ID为userDao, 这样便于自动注入到UserService对象中.
@Repository("userDao") //指定特定的Bean ID 方便setUserDAO注入
public class OracleUserDao implements UserDao, Serializable{
重构UserService类,在属性设置方法setUserDao()上使用注解@Resource, 这样Spring就会自动的将前一步声明的userDao对象注入到当前UserService对象中. userDao引用变量不再为null
配置的方式可以使用Spring表达式的方式#{***.***}下面使用注解的方式
十:使用@Value将db.properties文件中的jdbc参数注入到JdbcDataSource中
在src下新建db.properties文件,保存jdbc配置参数完整代码如下
Dirver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:XE
user=openlab
pwd=open123
更新applicationContext.xml文件,将db.properties读取到Spring中代码片段如图所示
<util:properties id=”jdbcProps” location=”classPath:db.properties”/>
2. 重构JdbcDataSource类, 使用@Value和Spring表达式配合将db.properties文件中的JDBC配置信息注入到JdbcDataSource属性中, 其中driver属性一定在setDriver方法上声明, 否则不能正确注册JDBC Driver.
/** 组件注解 */
@Component
public class JdbcDataSource implements Serializable{
private String driver;
@Value("#{jdbcProps.url}")
private String url;
@Value("#{jdbcProps.user}")
private String user;
@Value("#{jdbcProps.pwd}")
private String pwd;
public String getDriver() {
return driver;
}
/** 必须使用Bean属性输入, 否则不能进行JDBC Driver注册 */
@Value("#{jdbcProps.driver}")
public void setDriver(String driver) {
try{
//注册数据库驱动
Class.forName(driver);
this.driver = driver;
}catch(Exception e){
throw new RuntimeException(e);
}
}
. 添加MysqlUserDao类实现UserDao接口, 在MySQL上实现findByName方法,并且使用@Repository声明为存储组件, 在setDataSource方法上使用@Inject声明dataSource属性注入. 完整代码如下所示:
/** 持久层 注解 */
@Repository //指定特定的Bean ID
public class MysqlUserDao implements UserDao, Serializable{
private JdbcDataSource dataSource;
public MysqlUserDao() {
}
@Inject
public void setDataSource(
@Named("jdbcDataSource")JdbcDataSource dataSource) {
this.dataSource = dataSource;
}
public JdbcDataSource getDataSource() {
return dataSource;
}