Spring学习笔记--AOP和IOC、SSH整合

来源:互联网 发布:关于人工智能的建议 编辑:程序博客网 时间:2024/06/06 18:25
/*spring框架的作用和优点:提高系统结构的灵活性,降低组件的耦合度
spring框架容器:在容器中管理应用程序的各个组件,建立组件关联
1、容器特性:工厂特性,IOC和AOP的实现
BeanFactory<--继承--ApplicationContext
ClassPathApplicationContext
FileSystemApplicationContext
2、对bean组件的管理
id|name 用于指定组件的标识符,class用于指定组件实现类
<property name="costDAO"  ref="costDao">-----costDao是和set方法对应
id 和getBean对应

bean对象的创建模式   
a.Bean对象创建模式
    Spring容器支持Singleton和prototype两种模式创建对象。
默认为单例模式,想改变,用scope属性。
b.创建时机  
    单例模式对象在容器实例化时创建,想将创建延迟到getBean可以加lazy-init="true"
prototype模式对象在调用getBean时创建

c:初始化:
    静态代码块,构造方法,init-method属性可以指定一个方法当做初始化方法,在对象创建后自动执行。
destroy-method可以指定一个销毁方法,在对象被垃圾回收之前自动执行(仅对Singleton对象有效)

*/

String conf="applicationContext.xml";
ApplicationContext ac=new ClassPathXmlApplicationContext(conf);
//获取容器的Bean组件对象
CostDAO dao=(CostDao)ac.getBean("costDao");
dao.save();


name 与setter一致,ref是引用的注入名id
Spring框架的IOC机制:Inverse Of Controller 被称为控制反转,控制转移
会将对象的创建和关系指定这些逻辑交给第三方框架或容器负责,将这些控制
控制逻辑交给第三方负责,这样发生变更后,只要修改第三方配置就可以了。

DI  Dependency Injection 被称为依赖注入,Spring框架中IOC机制通过DI技术实现。DI的注入技术实现:
a、setter方法注入:用setter接受注入对象的实例,添加setter方法---采<property>描述》
<property name="costDAO" ref="costDao"></property>

b、constructor方法注入:添加带参构造方法,<constructor-arg>
<constructor-arg index="0" ref="hibernateCostDao"></constructor-arg>

DI注入的使用,可以通过注入技术注入各种不同类型的数据
1)注入一个Bean对象,采用ref="Bean的ID名称"
<property name="costDAO" ref="costDao"></property>

<property name="hbms">
    <list>
        <value>com/buaa/entity/a.hbm.xml</value>
    </list>
</property>

<property name="names">
    <set>
        <value>Tom</value>
    </set>
</property>

<property name="books">
    <map>
        <entry key="" value=""></entry>
    </map>
</property>

<property name="hbms">
    <props>
        <prop key="">com.buaa.entity.a.hbm.xml</prop>
    </props>
</property>


Set<String> set=books.keySet();
2)注入一个基本数据类型,采用value="值"
<property name="password" value="123456"></property>




Spring 框架的AOP机制
1)AOP 概念:Aspect Oriented Programming 面向方面编程
AOP与OOP的关系:
    AOP以OOP面向对象编程为基础。
    OOP侧重点在于对象,因此如何构建对象是OOP的重点。
    AOP的侧重点是方面,即共通功能部分。以低耦合的形式实现调用。
AOP关注的是共通处理问题,可以将共通处理封装成一个组件(方面组件)
,然后采用AOP机制可以以低耦合方式作用到指定的目标组件上。
<!--利用AOP机制-->
<bean id="logBean" class=""></bean>
    <aop:config>
        <!--切入点,指定目标组件-->
        <aop:pointcut id="actionPointcut" expression="within(目标组件的路径)"/>
        <!--expression="execution(* show*)"-->
        <!--将logBean定义为方面组件-->
        <aop:aspect id="logAspect" ref="logBean">
            <!--通知,指定logBean功能在action方法之前作用-->
            <aop:before pointcut-ref="actionPointcut" method="logger"/>
        </aop:aspect>
    </aop:config>
AOP使用步骤:
    1、引入Spring的IOC和AOP开发包cglib-
    2、添加Spring容器的配置文件
    3、将共通处理封装成一个独立的Bean组件
    4、采用AOP配置将Bean组件作用到其他目标组件及其方法上
AOP相关概念:
    1、方面(Aspect):方面指的是封装共通处理的组件,可以灵活的切入到目标对象及方法上。
    2、切入点(Pointcut):用于指定目标对象和方法,指的是一个表达式,利用表达式指定目标对象及方法
    3、连接点(JoinPoint):连接点值得是方面和某一个目标方法的关联点。切入点是连接点的集合。
    4、通知(Advice):用于指定方面功能在目标对象方法上执行的时机,(方法前,方法后,异常发生)。
    5、目标组件(Target):使用方面功能的目标组件,或切入点指定的Bean组件。
    6、动态代理(AutoProxy):动态代理机制是AOP机制的实现原理。Hi
    bernate的延迟加载就是。Spring框架在使用AOP配置后,返回的Bean对象,是采用动态代理机制生成的一个新类型。
    该类型的方法负责执行方面组件和目标组件的处理。Spring框架采用了两种方式生成动态代理。
    ---采用CGLIB工具生成(目标对象没有接口)
        public class 代理类 extends 原目标组件{重新原目标组件的方法}
    ---采用JDK Proxy API生成(目标对象有接口)
        public class 代理类 implements 原目标组件接口{实现原目标组件接口}


切入点表达式:利用表达式指定目标组件及方法。
    1、方法限定表达式
        execution(修饰符?返回类型 方法名(参数列表) throws 异常?)
        execution(public void addCost(Cost cost) throws Exception)
        例子1:匹配容器中的所有组件以add开始的方法
            execution(* add*(..))
        例子2:匹配CostService组件的所有方法
            execution(*com.buaa.service.costService.*(..))
        例子3:匹配service包下所有类的所有方法
            execution(*com.buaa.service.*.*(..))
        例子4:匹配service包下及其子包中所有类的所有方法
            execution(*com.buaa.service..*.*(..))

    2、类型限定表达式
        wuthin(类型)
        例子1、匹配CostService类中的所有方法
            within(con.buaa.service.CostService)
        例子2、匹配service包下所有类的所有方法
            within(con.buaa.service.*)
        例子3、匹配service包下及其子包中所有类的所有方法
        within(con.buaa.service..*)
    3、Bean名称限定表达式
        bean(Bean的id或name属性值)
            例子:bean(*DAO),bean(costAction)
    
通知类型:
    前置通知,<aop:before>方面组件在目标方法之前调用、
    后置通知,<aop:after-returnning>方面组件在目标方法之后调用,如果目标方法抛出异常,将不再执行方面组件、
    最终通知,<aop:after>之后调用,有无异常都会执行、
    异常通知,<aop:after-throwing>抛出异常后执行、
    环绕通知,<aop:around>、之前之后都要执行

Spring注解配置的使用:>jdk5.0
1)<bean>元素和注入的配置
组件扫描技术方法:1、applicationContext.xml中开启组件扫描功能,指定要扫描的package路径/2、
想要组件扫描到Spring容器,需要标记---@Controller --@Service  --@Repository  @Component
默认扫描到容器采用类名首字母小写当id值,如果需要修改,@Service("id值")。
两个组件之间有注入关系,可以在变量定义前或setter定义前使用如下注解
---@Resource(name="costDao")  --@Autowired

    <!--开启组件扫描注解-->
    <context:component-scan base-package="com.buaa"/>

2)<aop>元素配置
1、在applicationContext.xml中开启AOP注解配置
2、在方面组件使用一下注解标记。
    --@Aspect//将Bean组件定义成方面,类定义前使用
    --@Pointcut//定义切入点表达式,方法定义前使用。需要写个空方法,才能使用。
    --@Around,@Before,@After,@AfterReturning,@AfterThrowing方法前使用

    
    <!--开启AOP注解配置-->
    使用方法:<aop:aspectj-autoproxy/>

    

    @Component//将组件扫描到Bean容器
    @Aspect//将该组件定义成方面组件

    @PointCut("within(com.buaa.action..*)")//必须在方法前使用
    public void p(){}
    @Around("p()")//环绕通知处理方法
    @AfterThrowing(PointCut="p()" throwing="ex")//记录目标方法抛出异常信息
    注解版:<!--开启组件扫描注解-->
        <context:component-scan base-package="com.buaa"/>
        DAOclass里加@Repository  
        加set要注入的对象的方法 //将容器中的SessionFactory给daoSupport传入,用于实例化HibernateTemplate
        @Resource
        getBean("类名首字母小写来取得信息");

    <!--开启AOP注解配置-->
    使用方法:<aop:aspectj-autoproxy/>

    --------------------------------------------------------------------------------------------------------
利用Spring整合JDBC和Hibernate
1)Spring框架对数据库访问技术提供了一下支持
    a.提供了一致的异常处理层次  DataAccessException
    b.提供了编写DAO的工具类,DaoSupport和Template 两种封装类型
        JDBC技术:JdbcDaoSupport ,JdbcTemplate
        Hibernate技术:HibernateDaoSupport,HibernateTemplateS
    c.提供了事物管理的支持,只需添加AOP配置即可。
2)Spring 和JDBC整合

引入jar包--src下建立applicationContext.xml--实体类--DAO接口--
JdbcCostDAO实现类,继承JdbcDaoSupport,方法体中使用JdbcTemplate类完成增删改查操作
    -update:用于增、删、改
    -queryForObject:用于查询一条记录
    -query:用于查询多条记录
    -queryForInt:用于查询一个数值的
--将JdbcCostDAO在Spring容器中定义
--追加一个连接池,在Spring中定义一个DataSource组件Bean对象,
并将Bean组件对象给JdbcCostDAO注入.(JdbcDaoSupport里有一个setDataSource方法,
接收容器注入的DataSource对象,利用DataSource对象实例化JdbcTemplate。)

public class JdbcCostDao
extends JdbcDaoSupport implements CostDAO{
    public void delete(Cost cost){
        String sql="delete from COST where id=?";
        Object[] params={cost.getId()};
        this.getJdbcTemplate().update(sql,params);
    }

    public void save(Cost cost){
        String sql="insert into...";
        Object[] params={cost.getName(),cost.getCost()};
        this.getJdbcTemplate().update(sql,params);
    }

    public void update(Cost cost){
        String sql="update COST set...";
        Object[] params={cost.getName(),cost.getCost()};
        this.getJdbcTemplate().update(sql,params);
    }

    public Cost findById(int id){
        String sql="select * from COST where ID=?";
        Object[] params={id};
        //public class A implements RowMapper{}
        A mapper=new A();
        return (Cost)this.getJdbcTemplate().queryForObject(sql,params,mapper);
        
    }

    public List<Cost> findAll(){
        String sql="";
        A mapper=new A();
        Object[] params={cost.getName(),cost.getCost()};
        return this.getJdbcTemplate().query(sql,params,mapperS);
    }

    public int count(){
        String sql="select count(*) from COST";
        int c=this.getJdbcTemplate().queryForInt(sql);
        return c;
    }
}
//建立applicationContext.xml
<bean id="costDao" scope="singleton" class="com.buaa.dao.impl.JdbcCostDao">
    <property name="dataSource" ref="myDataSource"></property>
</bean>
//定义连接池的Bean
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="username" value="yansu1"></property>
    <property name="password" value="123"></property>
    <property name="driverClassName" value="oracle.jdbc.DriverManager.orcl"></property>
    <property name="url" value="jdbc:oracle:thin:@localhost:8080"></property>
</bean>
public class TestCost{
    public void test1(){
        String conf="applicationContext.xml";
        ApplicationContext ac=new ClassPathXmlApplicationContext(conf);
        CostDAO costDao=(CostDao)ac.getBean("costDao");
        
    }
}


Spring 整合Hibernate
public class HibernateDaoSupport implements CostDAO{
    public void delete(Cost cost){
        this.getHibernateTemplate().delete(cost);
    }

    public void save(Cost cost){
        this.getHibernateTemplate().save(cost);
    }

    public void update(Cost cost){
        this.getHibernateTemplate().update(cost);
    }

    public Cost findById(int id){
        //return this.getHibernateTemplate().get(Cost.class,id);
        String hql="from Cost where id=?";
        Object[] params={id};
        List<Cost> list=this.getHibernateTemplate().delete(hql,params);
        if(list.isEmpty()){
            return null;
        }else{
            return list.get(0);
        }
    }

    public List<Cost> findAll(){
        String hql="from Cost";
        return this.getHibernateTemplate().find(hql);        
    }

    public int count(){
        String hql="select count(*) from Cost";
        List list=this.getHibernateTemplate().find(hql);
        int c=new Integer(list.get(0).toString());
        return c;
    }
}


xml:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" class="classpath:hibernate.cfg.xml"></property>
    <!--连接参数信息-->
    <property name="dataSource" ref="myDataSource"></property>
    <!--hibernate参数-->
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect"></prop>
            <prop key="show_sql">true</prop>
            <prop key="format_sql">true</prop>
        </props>
    </property>
    <!--hbm.xml-->
    <property name="mappingResouces">
        <list>
            <values>Cost.hbm.xml</values>
        </list>
    </property>
</bean>

<bean id="costDao" class="org.">
    <property name="sessionFacory" ref="sessionFactory"><>
</bean>

--spring,ojdbc,dbcp,hibernate jar
--applicationContext.xml
--实体类 ,映射描述文件
--CostDAO接口
--实现类HibernateCostDAO(继承HibernateDaoSupport,采用HibernateTemplate实现增删改查)
--Spring容器配置HibernateCostDAO   需要事先定义DataSource,SessionFactory
组件对象,按DataSource注入
--SessionFactory注入
--HibernateCostDAO顺序建立关联


Spring 和Struts整合
web.xml  <filter></filter>
            <context-param>//位ContextLoaderListener指定spring容器的配置文件
                <param-name>contextConfigLocation</param-name>//contextConfigLocation是listener的默认找的名字
                <param-value>clsspath:aaplicationContext.xml</param-value>
            </context-param>
         <listener></listener>//启动tomcat实例化spring容器对象,相当于实例化容器那段代码
struts.xml里<!DOCTYPE....dtd>  
    <struts>
        <package name="demo1" extends="struts-default">
            <!--hello.action--DemoAction--demo.jsp-->
            //加入struts-spring-plugin.jar,class="demoAction",是容器里的action名
            <action name="hello" class="com.buaa.action.DemoAction">
                <result>/demo.jsp</result>
            </action>
        </package>
    
    </struts>

步骤:
    1、导包
    2、添加Struts控制器配置和struts.xml配置文件
    3、引入struts-spring-plugin.jar,然后为<action>配置class指定为spring容器中Action组件定义的id值。
    plugin整合包提供一个StrutsSpringObjectFactory,采用该组件获取Action对象,该组件可以访问spring容器,获取容器中定义的Bean对象。
        a.<action>的class属性去spring找Bean的id=class值。
        b.<action>的class找不到Bean,ObjectFactory利用类反射创建
        一个action对象,再访问spring容器,将容器中的id名和Action属性一致的Bean对象注入给
        Action。
    
        try{
        //第一种利用class值去spring获取Bean对象
        }catch(){
        //第二种自己创建一个Action,之后将Spring中的Bean对象给Action属性注入。
        //名称匹配注入,规则是set属性名=容器的id值。
        }

    4、在web.xml中添加ContextLoaderListener组件,用于启动服务器时实例化spring容器
    
    log4j.properties
Spring struts整合 注解版:
    1、<!--组件扫描-->
        <context:component-scan base-package="com.buaa">
        </context:component-scan>
    2、DAO里加@Repository  加setSessionFactory方法,上面注解@Resource
    3、Action里加@Controller setDAO方法上加@Resource  id值为类名首字母小写
    
Spring对hibernate延迟加载操作的支持:Spring 提供了 Filter 组件OpenSessionInviewFilter
可以在web.xml中定义该filter,这样可以将Template方法关闭Session时机推迟到JSP解析之后。
注意:定义在StrutsFilter之前才有效


//Spring的事务管理:
spring提供了两种事务管理:
    *1、声明式事务管理
        以AOP配置的形式实现事物管理
方面组件:JDBC(DataSourceTransactionManager)
        Hibernate 事务管理方面的组件:(HibernateTransactionManager)
事物管理通知:<tx:advice>
切入点:实际情况写表达式
    2、编程式事务管理:事务管理代码使用TransactionTemplate
//定义事物管理Bean
<bean id="txManager" class="springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"></property>    
</bean>
//定义通知
<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="find*" read-only="true" propagation="REQUIRED"/>
        <tx:method name="save*" propagation="REQUIRED"/>
        <tx:method name="update*" propagation="REQUIRED"/>
        <tx:method name="delete*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>
//AOP配置,将通知和切入点(目标对象)结合
<aop:config>
    //将所有DAO当做目标
    <aop:pointcut id="servicepointcut"
    expression="within(com.buaa.gbook.dao..*)"/>
    //关联Advice和Pointcut
    <aop:advisor advice-ref="txAdvice" pointcut-ref="servicepointcut"/>    
</aop:config>

------------------------
采用注解方式配置事务
 首先在applicationContext中开启事务注解,
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory">
    </property>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>
然后在目标组件中使用@Transactional.该标记可用在类定义和方法定义前。
类定义前指定全局,方法定义前指定当前方法。
------------------------

Spring MVC框架

0 0
原创粉丝点击