Spring

添加Spring配置,还有日志功能,一共3个jar包。
commons-logging.jar
log4j-1.2.15.jar
spring.jar
Spring两大核心功能,控制反转IoC和面向切面编程AOP的使用。

IoC的理解

依赖注入的概念
控制反转模式的基本概念:当某个Java对象需要依赖另一个Java对象时,不是自身直接创建依赖对象,而是由实现IoC的容器(如Spring框架的IoC容器)来创建,并将它注入需要这个依赖对象的Java对象中。
通过利用IoC模式的IoC容器,创建依赖对象的过程交由IoC容器实现,然后IoC容器会使用适当的方式(如调用set方法)把这个依赖对象注入到本类中的实例中,从而实现互相依赖的对象之间实现了松耦合。

Spring的依赖注入,有两种方式,一种是构造器注入,一种是setter注入。
构造器注入和设置注入方式


    /** 带参数的构造方法 */
    public AccountServiceImpl(AccountDao accountDao){
        System.out.println("constructor");
        this.accountDao = accountDao;
    }
        /** set方法 */
    public void setAccountDao(AccountDao accountDao) {
        System.out.println("setAccountDao");
        this.accountDao = accountDao;
    }
    //其他业务逻辑代码

同时,在applicationContext.xml中进行如下配置,另外一种是设置注入方式。这里,如果想要选择mysql,就直接用上面的bean,不要用下面的,注释掉就好了!很简单吧~~~

    <!-- 配置由Spring容器来管理Bean -->
    <!-- <bean id="accountDao" class="com.qiujy.dao.AccountDaoMySQLImpl"/> -->
    <bean id="accountDao" class="com.qiujy.dao.AccountDaoOracleImpl"/>


    <bean id="accountService" class="com.qiujy.service.AccountServiceImpl">
        <!-- 构造器注入方式
        <constructor-arg ref="accountDao"/>
        -->
        <!-- 设置注入方式 -->
        <property name="accountDao" ref="accountDao"/>
    </bean>

spring_01_start

Spring的容器

Spring管理的基本单元是Bean,在Spring的应用中,所有的组件都是一个个的Bean,Spring负责其生命周期。Spring容器有两个接口,BeanFactory和ApplicationContext。这两个接口的实例被称为Spring上下文。它们都可以用来生产Bean,即负责创建和管理Bean。

//创建一个Spring的Bean工厂(IoC容器)
        BeanFactory factory = new ClassPathXmlApplicationContext("classpath:application*.xml");
        //通过AccountService这个id从Spring的Bean工厂中获取一个实例
        AccountService service = (AccountService)factory.getBean("accountService");
        //调用业务方法
        service.save("test", "123");

使用xml装配Bean

装配Bean,Bean有9个属性,列举如下:

id
class
name
autowire 指定该Bean属性的装配方式
scope 指定该Bean的存在范围
init-method 
destroy-method
abstract 指定该Bean是否为抽象的。如果是抽象的,则Spring不为它创建实例。
parent 指定该Bean的父类标识或别名

spring_02_ioc
Bean1.java
Bean2.java
Bean3.java
Bean4.java
Bean5.java
Bean6.java
Child.java
Parent.java

可以去看Bean怎样用xml装载的。

AOP

spring_03_aop

面向切面编程,不是OOP的代替,而是对它的一种有益补充!更加专注于业务逻辑,而把日志,事务和安全验证服务 抽离出来,做一个切面编程!

有两种方式实现AOP
1:通过xml配置文件的AOP实现
把日志服务类LogAspect类作为一个切面,所以需要在Spring配置文件中把它配置为一个切面。

<?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:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <bean id="accountDao" class="com.qiujy.dao.AccountDaoMySQLImpl"/>

    <bean id="accountService" class="com.qiujy.service.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"/>
    </bean>

    <!-- 日志切面类 -->
    <bean id="logAspectBean" class="com.qiujy.aspect.LogAspect"/>

    <!-- AOP配置 -->
    <aop:config>
        <!-- 配置一个切面 -->
        <aop:aspect id="logAspect" ref="logAspectBean">
            <!-- 定义切入点,指定切入点表达式 -->
            <aop:pointcut id="allMethod" 
                expression="execution(* com.qiujy.service.*.*(..))"/>

            <!-- 应用前置通知 -->
            <aop:before method="before" pointcut-ref="allMethod" />
            <!-- 应用后置通知 -->
            <aop:after-returning method="afterReturn" pointcut-ref="allMethod"/>
            <!-- 应用最终通知 -->
            <aop:after method="after" pointcut-ref="allMethod"/>
            <!-- 应用抛出异常后通知 -->
            <aop:after-throwing method="afterThrowing" pointcut-ref="allMethod"/>

            <!-- 应用环绕通知,只需要定义前面或者后面的方法就好,不需要全部定义!
            <aop:around method="doAround" pointcut-ref="allMethod" />
            -->
        </aop:aspect>
    </aop:config>
</beans>

定义需要在方法执行前,return后,和全部执行完,抛出异常和全部(doAround),的时候执行切面操作。

第二种方式:通过注解的AOP实现
需要在Spring配置文件中启用对AspectJ注解的支持!
applicationContext-anno.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:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <bean id="accountDao" class="com.qiujy.dao.AccountDaoMySQLImpl"/>

    <bean id="accountService" class="com.qiujy.service.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"/>
    </bean>

    <!-- 把切面类交由Spring容器来管理 -->
    <bean id="logAspectBean" class="com.qiujy.aspect.LogAnnotationAspect"/>

    <!-- 启用spring对AspectJ注解的支持 -->
    <aop:aspectj-autoproxy/>
</beans>

然后在LogAnnotationAspect类中,用注释的方法增加切入点。

/**
 *  ClassName: LogAspect.java
 *  created on 2008-12-10
 *  Copyrights 2008 qjyong All rights reserved.
 *  EMail: qjyong@gmail.com
 */
package com.qiujy.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
 * 日志切面类
 */
@Aspect  //定义切面类
public class LogAnnotationAspect {
    @SuppressWarnings("unused")
    //定义切入点
    @Pointcut("execution(* com.qiujy.service.*.*(..))")
    private void allMethod(){}

    //针对指定的切入点表达式选择的切入点应用前置通知
    @Before("execution(* com.qiujy.service.*.*(..))")
    public void before(JoinPoint call) {

        String className = call.getTarget().getClass().getName();
        String methodName = call.getSignature().getName();

        System.out.println("【注解-前置通知】:" + className + "类的" 
                + methodName + "方法开始了");
    }
    //访问命名切入点来应用后置通知
    @AfterReturning("allMethod()")
    public void afterReturn() {
        System.out.println("【注解-后置通知】:方法正常结束了");
    }

    //应用最终通知
    @After("allMethod()")
    public void after(){
        System.out.println("【注解-最终通知】:不管方法有没有正常执行完成," 
                + "一定会返回的");
    }

    //应用异常抛出后通知
    @AfterThrowing("allMethod()")
    public void afterThrowing() {
        System.out.println("【注解-异常抛出后通知】:方法执行时出异常了");
    }

    //应用周围通知
    //@Around("allMethod()")
    public Object doAround(ProceedingJoinPoint call) throws Throwable{
        Object result = null;
        this.before(call);//相当于前置通知
        try {
            result = call.proceed();
            this.afterReturn(); //相当于后置通知
        } catch (Throwable e) {
            this.afterThrowing();  //相当于异常抛出后通知
            throw e;
        }finally{
            this.after();  //相当于最终通知
        }

        return result;
    }
}

Spring对JDBC的支持

spring_05_jdbc
需要用到数据库支持的jar,还有切面的aspectjrt,weaver, cglib用来压缩(不懂),commons-dbcp数据库连接方式等,还可以选择c3p0这种数据源连接方式。(不懂)
commons-logging.jar
log4j-1.2.15.jar
spring.jar
aspectjrt.jar
aspectjweaver.jar
cglib-nodep-2.1_3.jar
mysql-connector-java-5.1.6-bin.jar
commons-dbcp.jar
commons-pool.jar
c3p0-0.9.1.2.jar

数据源的注入

<?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:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <!-- 配置不带连接池的数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql:///spring_04" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>

    <!-- 配置DBCP的数据源 -->
    <bean id="dataSource2" 
          class="org.apache.commons.dbcp.BasicDataSource" 
          destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///spring_04" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>

    <!-- 配置C3P0的数据源 -->
    <bean id="dataSource3"
          class="com.mchange.v2.c3p0.ComboPooledDataSource"
          destroy-method="close">
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql:///spring_04" />
        <property name="user" value="root" />
        <property name="password" value="root" />
    </bean>

    <!-- 根据JNDI获取数据源 
    <bean id="dataSource4" 
           class="org.springframework.jndi.JndiObjectFactoryBean">       
        <property name="jndiName" value="jdbc/TestSpring" />
        <property name="resourceRef" value="true" />
    </bean>
    -->

    <bean id="accountDao" class="com.qiujy.dao.AccountDaoJDBCImpl">
        <property name="dataSource" ref="dataSource3" />
    </bean>

    <bean id="accountService" class="com.qiujy.service.AccountService">
        <property name="accountDao" ref="accountDao"/>
    </bean>
</beans>

service通过DAO接口,进行业务逻辑,在DAO中,设置数据源。

    AccountService service = (AccountService)context.getBean("accountService");
AccountService 中有一个字段.
    private AccountDao accountDao;

    //setter注入
    public void setAccountDao(AccountDao accountDao){
        this.accountDao = accountDao;
    }

数据源注入有3种方式。
1 不带连接池的数据源。
2 集成第三方连接池技术的数据源。比较常用的有:DBCP 和C3P0。第三方连接,需要commons-dbcp和commons-pools.jar
3 从JNDI中获取数据源*(不懂)

Spring对JDBC的支持

spring_05_jdbc
在使用JDBC来操作数据库时,要处理很多同样的琐碎的细节,如:获取数据库连接、创建Statement、处理数据库异常、关闭数据库资源等。Spring针对这种情况提供了几个类来简化JDBC API的使用。

3种 ,使用JdbcTemplate类、使用NamedParameterJdbcTemplate类、使用SimpleJdbcTemplate类。

    public void create(Account acc) {
        String sql = "INSERT INTO account(loginname,password,email,"
                +"cellphone,registed_time) VALUES(?,?,?,?, NOW())";

        Object[] paramValues = {acc.getLoginname(), acc.getPassword(), 
                acc.getEmail(),acc.getCellphone()};

        this.jdbcTemplate.update(sql,paramValues);
    }


    @SuppressWarnings("unchecked")
    public List<Account> findAll() {
        String sql = "SELECT * FROM account";
        return this.jdbcTemplate.query(sql, new AccountRowMapper());
    }

    public Account findById(Long id) {
        String sql = "SELECT * FROM account WHERE id=?";
        Object[] paramValues = {id};
        return (Account)jdbcTemplate.
                    queryForObject(sql, paramValues, new AccountRowMapper());
    }

    //把结果集封装成Account对象的包装类
    private static final class AccountRowMapper implements RowMapper {
        public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
            Account acc = new Account();
            acc.setId(rs.getLong("id"));
            acc.setLoginname(rs.getString("loginname"));
            acc.setPassword(rs.getString("password"));
            acc.setEmail(rs.getString("email"));
            acc.setCellphone(rs.getString("cellphone"));

            Timestamp temp = rs.getTimestamp("registed_time");
            if(temp != null){
                acc.setRegistedTime(new Date(temp.getTime()));
            }
            return acc;
        }
    }

NamedParameterJdbcTemplate类

public class AccountDaoNamedParameterJdbcTemplateImpl implements AccountDao {
    //带命名参数功能的Jdbc模板类实例
    private NamedParameterJdbcTemplate jdbcTemplate;

    public void setDataSource(DataSource dataSource){
        jdbcTemplate  = new NamedParameterJdbcTemplate(dataSource);
    }

    public void create(Account acc) {
        String sql = "INSERT INTO account(loginname,password,email,"
                + "cellphone,registed_time) "
                + "VALUES(:loginname,:password,:email,:cellphone, NOW())";
        //使用一个Bean对象的属性值作为命名参数的值
        SqlParameterSource namedParameters = 
                new BeanPropertySqlParameterSource(acc);

        this.jdbcTemplate.update(sql,namedParameters);
    }
...
}

SimpleJdbcTemplate类


/**
 * 使用SimplateJdbcTemplate来实现AccountDao接口
 */
public class AccountDaoSimpleJdbcTemplateImpl implements AccountDao {
    private SimpleJdbcTemplate jdbcTemplate;

    public void setDataSource(DataSource dataSource){
        jdbcTemplate  = new SimpleJdbcTemplate(dataSource);
    }

    public void create(Account acc) {
        String sql = "INSERT INTO account(loginname,password,email,"
                +"cellphone,registed_time) VALUES(?,?,?,?, NOW())";

        this.jdbcTemplate.update(sql, acc.getLoginname(),
                                      acc.getPassword(), 
                                      acc.getEmail(),
                                      acc.getCellphone());
    }
...
}

这个功能更强大一些!

上述全部代码:
http://download.csdn.net/detail/chengyangyy/9122815

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值