码迷,mamicode.com
首页 > 其他好文 > 详细

ssm aop

时间:2018-10-16 01:50:15      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:span   type   attribute   signature   实现   private   read   安装   order   

1.基于半配置半注解的AOP(依赖在最底下)

配置

        <!--扫描的包-->
        <context:component-scan base-package="cn.test.service"/>
        <!--开启aop注解,proxy-target-class属性设置为true表示强制使用CGLIB代理-->
        <aop:aspectj-autoproxy/>

 被切入方法

@Service("aop")
public class AOPTest {
    public  int   add(int a,int b){
        return  a+b;
    }

    public  Object   sub(int a,int b){//该实例是在环绕通知中使用,所有返回值是object类型,否则报异常
        return  a-b;
    }

    public  int   mul(int a,int b){
        int  i=10/0;
        return  a-b;
    }
}

 切入点

@Order(2)//指定切面的优先级,值越小优先级越高.
@Aspect
@Service
public class AOPInfo {

    /*重用切入表达式,@Pointcut注解方法的访问权限符(public,private等)控制着重用切入表达式的可见性,
    声明为 public时,在不同的包下需要写包名,相同的包下不用写包名*/
    @Pointcut("execution(* cn.test.service.*.add(..))")
    public  void  PointCut(){
        System.out.println("PointCut--");
    }

    //前置通知
    //使用重用表达式,PointCut()是注解 @Pointcut的方法名,
    @Before("PointCut()")
    public  void   before(){
        System.out.println("before--");
    }
    //后置通知,没有返回值
    @After("PointCut()")
    public  void   after(){
        System.out.println("after--");
    }

    //返回通知,有返回值
    @AfterReturning(value = "PointCut()",returning ="result")
    public  void   afterReturning(JoinPoint joinPoint,Object result){
        String name = joinPoint.getSignature().getName();
        System.out.println("afterReturning--"+name+":"+result);
    }
    //异常通知
    @AfterThrowing(value = "execution(* cn.test.service.*.mul(..))",throwing = "ex")
    public  void  afterThrowing(JoinPoint joinPoint, Exception  ex){
        String name = joinPoint.getSignature().getName();//获取方法名
        System.out.println("afterThrowing--"+name+":"+ex);
    }

    //环绕通知,被拦截的方法的返回值类型需要是object类型,否则报错,其他通知没有这个特征
    @Around(value = "execution(* cn.test.service.*.sub(..))")
    public  void   around(ProceedingJoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();//获取方法名
        System.out.println(name+":before--");//前置通知
        try {
            System.out.println(name+":after--");//后置通知
            Object result = joinPoint.proceed();//获取返回值
            System.out.println("afterReturning--"+name+":"+result);//返回通知
        } catch (Throwable throwable) {
            System.out.println("afterThrowing--"+name+":"+throwable);//异常通知
        }
        System.out.println("around--");//环绕通知
    }
}

备注:

ProceedingJoinPoint类的方法:

Getargs方法 获取目标方法的参数

Getsignature方法:返回切入表达式的相关信息

Getarget方法:换回切入表达式的对象

Getthis:返回aop框架为目标对象生成的代理对象

proceed():获取返回值

 

切入点表达式的语法

完整的语法:Execution (“modifiers-pattern  ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)throw-pattern”)

说明:execution:匹配执方法的连接点

modifiers-pattern 权限修饰符  可省略

ret-type-pattern 返回值类型 支持通配

declaring-type-pattern指定方法所属的类 支持通配 可省略//例如:@Before("execution(* spring2..*(int, int))")

name-pattern方法名 支持通配

param-pattern ..代表两个任意的参数假如是*则是代表一个任意类型的参数

throw-pattern 声明抛出异常 支持通配 可省略

例如:@Before("execution(* spring2.*.*(int, int))")第一个*表示返回类型 第二个*表示类名 第三个表示方法

 

2.完全依赖配置的AOP

重新整理待续

 

3.完全基于注解的AOP

重新整理待续

 

 

 

 

 

 

 

 

3.4) 合并切入点表达式

切入点表达式可以通过操作符 &&, ||, ! 结合起来

4)指定切面的优先级

<bean id="atime" class="spring2.AtithmeticCalculatorimp"></bean>
<aop:aspect ref="atime" order="2">

可以通过@Order 注解指定(在类上指定),值越小 优先级越高.

 


6)基于xml的声明切面

所有的 Spring AOP 配置都必须定义在 <aop:config> 元素内部,. 对于每个切面都要创建一个 <aop:aspect> 元素,切入点必须定义在 <aop:aspect> 元素下

<!—对每个方法都进行匹配扫描  -->

<bean id="atime" class="spring2.AtithmeticCalculatorimp"></bean>

<aop:config >

       <!-- ref指向bean的id ,指定切面的对象,也就是@aspect注解的对象-->
       <aop:aspect ref="atime" order="2" >

       <!--切面表达式-->
       <aop:pointcut expression="execution(* spring2.*.*(int, int))" id="pointcut"/>

       <!--前置使用在beforeMethod方法上-->
       <aop:before method="beforeMethod" pointcut-ref="pointcut"/>

       <!--后置使用在afterMethod方法上 pointcut切入点表达式-->
       <aop:after method="afterMethod" pointcut="execution(* spring2.*.*(int, int))"/>

       <aop:after-returning method="returningMethod" pointcut-ref="pointcut" returning="result"/>

       <aop:after method="afterthrow" pointcut-ref="pointcut"/>

       <aop:around method="aroundmethod" pointcut-ref="pointcut" />

       </aop:aspect>

</aop:config>

 

 

 

 

 

3.事务管理

1)事务管理的原理

1>无论使用 Spring 的哪种事务管理策略(编程式或声明式), 事务管理器都是必须的,使用hibernate是管理事物的是session(session.transaction),spring策略是通过platformtransactionmanager接口实现,其中有三个方法gettransaction  获事务的方法,commit提交事务的方法,rollback回滚事物的方法,这个是没有与任何事务资源捆绑在一起,可以适应于任何的事务策略,spring没有任何的事物支持,只是包装了底层事务

2 >Gettransaction方法根据transactiondefinition参数,返回一个transactionstatus对象表示一个事务,transactionstatus被关联在当前的线程上

3 >Transactiondefinition接口定义一个事务规则,必须指定事务的隔离,事务的传播,事务的超时,只读状态

2)事务管理的方式

编程式事务管理

通过上述的三个方法实现,较为麻烦

声明式事务管理

Aop实现:在目标方法执行之前,切入开始事务,在目标方法执行之后,切入结束事务

方式1:

在xml中配置事物管理

<!-- 配置事务管理器  使用datasource.DataSourceTransactionManager  该类实现了platformtransactionmananger接口-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!—配置platformtransactionmananger接口,针对采用数据库连接的特定实现 -->
    <property name="dataSource" ref="datasource"></property>
</bean>
<!—配置事物的切入点,指定事务管理器 transaction-manager="transactionManager"当transaction-manager 的值为transactionManager 时这个属性可以省略,不是则需要添加--> <tx:advice id="txAdvice" transaction-manager="transactionManager">     <!—只能匹配一个 tx:attributes 可以匹配多个tx:method --> <tx:attributes> <!-- 根据方法名指定事务的属性 --> <tx:method name="purchase" propagation="REQUIRES_NEW"/> <!—所有以get开头的方法 read-only 只读模式-->        <tx:method name="get*" read-only="true"/>             <!—所有以find开头的方法 --> <tx:method name="find*" read-only="true"/> <!—所有方法 --> <tx:method name="*"/> </tx:attributes> </tx:advice>
<!-- aop 配置在那些元素上 --> <aop:config> <aop:pointcut expression="execution(execution(* spring2.*.*(int, int))id="txPointCut"/> <!—与aop绑定在一起,当切入点切入时,txAdvice 定义的处理也被切入,advisor 是从spring1.x中保留的,作用是将advice和切入点绑定在一起,然后一起切入 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config>

说明:tx:advice包含事务的隔离,传播,超时属性,只读,对指定事务的回滚,对指定事务不回滚等

tx:method的属性如下

Name:必选属性  配置关联的方法名,支持通配符 例如get* handle* on*event等

Propagation:事务的传播(在已经有事务的前提下,调用另外一个事务的情形),该属性为Propagation的枚举值,默认值为PROPAGATION_REQUIRED支持当前事务(在事务中,就不新建事务),如果当前没有事务,就新建一个事务,PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

Isolation:隔离级别isolation枚举的值,默认值是ISOLATION_DEFAULT,ISOLATION_READ_UNCOMMITTED读未提交,ISOLATION_READ_COMMITTED读已提交,ISOLATION_REPEATABLE_READ可重复读,ISOLATION_SERIALIZABLE序列化

Timeout:指定事务的超时时间

Read-only 是否只读

Rollback-for 事务回滚的异常类,需要使用全类名,多个用逗号隔开

No-rollback-for:指定不触发事务回滚的异常类,其余同上

说明:在默认的情况下,只有在运行时异常和unchecked异常时,spring事务才会回滚,如果抛出checked异常时,则事务不会回滚,假如需要回滚需要设置rollback-for属性,如果希望抛出指定的异常不回滚,那么需要设置no-rollback-for

方式2

使用@transactional配置事务管理

在方法上指定@transactional,表示在这个方法上具有事务性

@transactional可指定的方法,属性值同上

需要在xml中配置

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="datasource"></property>
</bean>

<!-- 启动事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"/>

 

5.springide插件的安装springsource-tool-suite-3.9.6.RELEASE-e4.9.0-updatesite更加方便spring的书写

 

6. Spring 对 JDBC 的支持

1)JdbcTemplate

1> 配置JdbcTemplate

<context:property-placeholder location="classpath:jdbc.properties"/>
       <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
       <property name="user" value="${user}"></property>
       <property name="password" value="${password}"></property>
       <property name="jdbcUrl" value="${jdbcUrl}"></property>
       <property name="driverClass" value="${driverClass}"></property>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
       <property name="dataSource" ref="datasource"></property>
</bean>

2> 使用JdbcTemplate查询数据库的方法

execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句; 

update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;

batchUpdate方法用于执行批处理相关语句; 

query方法及queryforobject方法:用于执行查询相关语句;

queryforobject:单行查询

String  sql2="select * from users where id=1";

//需要注入的bean

RowMapper<Users> rm=new BeanPropertyRowMapper<>(Users.class);

Users users = jdbcTemplate.queryForObject(sql2, rm);

query:多行查询 返回list集合

String  sql3="select * from users where id>?";

RowMapper<Users> rm1 = new BeanPropertyRowMapper<>(Users.class);

List<Users> query = jdbcTemplate.query(sql3, rm1,0);

call方法:用于执行存储过程、函数相关语句。

备注:注意jdbcTemplate尽量只执行查询操作,莫要进行更新,否则很容易破坏Hibernate的二级缓存体系,但在一般与hibernate等使用时一般不会用到spring的JdbcTemplate,经典的 JDBC 用法中, SQL 参数是用占位符 ? 表示

2)NamedParameterJdbcTemplate

1> 具名参数只在 NamedParameterJdbcTemplate 中得到支持

2> 配置NamedParameterJdbcTemplate

<context:property-placeholder location="classpath:jdbc.properties"/>

<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
       <property name="user" value="${user}"></property>
       <property name="password" value="${password}"></property>
       <property name="jdbcUrl" value="${jdbcUrl}"></property>
       <property name="driverClass" value="${driverClass}"></property>
</bean>

<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"><constructor-arg ref="datasource"></constructor-arg>
</bean>

3)使用

NamedParameterJdbcTemplate namedParameterJdbcTemplate = ctx.getBean(NamedParameterJdbcTemplate.class);//获取对象
//使用别名:user,:password
String sql="insert into users(user,pwd) values(:user,:password)";
Map<String ,Object> paramMap=new HashMap<>();
paramMap.put("user", "12qwe");
paramMap.put("pwd", "weq");
namedParameterJdbcTemplate.update(sql, paramMap);

 

ssm aop

标签:span   type   attribute   signature   实现   private   read   安装   order   

原文地址:https://www.cnblogs.com/gg128/p/9795323.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!