SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)

接上一篇

SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP,本篇我们主要是来学习使用配置XML实现AOP

本文采用强制的CGLB代理方式

SecurityHandler这个通知类可以换成安全性检测、日志管理等等。

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.bjpowernode.spring;

import org.aspectj.lang.JoinPoint;

public class SecurityHandler {

	private void checkSecurity(JoinPoint joinPoint) {
		for (int i=0; i<joinPoint.getArgs().length; i++) {
			System.out.println(joinPoint.getArgs()[i]);
		}

		System.out.println(joinPoint.getSignature().getName());

		System.out.println("-------checkSecurity-------");
	}
}
</span></span></span>

UserManager接口

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.bjpowernode.spring;

public interface UserManager {

	public void addUser(String username, String password);

	public void delUser(int userId);

	public String findUserById(int userId);

	public void modifyUser(int userId, String username, String password);
}
</span></span></span>

UserManagerImpl接口的实现

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.bjpowernode.spring;

public class UserManagerImpl implements UserManager {

	public void addUser(String username, String password) {
		//checkSecurity();
		System.out.println("---------UserManagerImpl.add()--------");
	}

	public void delUser(int userId) {
		//checkSecurity();
		System.out.println("---------UserManagerImpl.delUser()--------");
	}

	public String findUserById(int userId) {
		//checkSecurity();
		System.out.println("---------UserManagerImpl.findUserById()--------");
		return "张三";
	}

	public void modifyUser(int userId, String username, String password) {
		//checkSecurity();
		System.out.println("---------UserManagerImpl.modifyUser()--------");
	}

//	private void checkSecurity() {
//		System.out.println("-------checkSecurity-------");
//	}
}
</span></span></span>

applicationContext.xml中进行配置( <!-- 强制使用CGLIB代理 -->  )

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><?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.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    <!-- 强制使用CGLIB代理 -->
    <!--
	<aop:aspectj-autoproxy proxy-target-class="true"/>
	 -->

	<bean id="userManager" class="com.bjpowernode.spring.UserManagerImpl"/>
	<bean id="securityHandler" class="com.bjpowernode.spring.SecurityHandler"/>

	<aop:config>
		<aop:aspect id="securityAspect" ref="securityHandler">
			<!--
			以add开头的方法
			<aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/>
			 -->
			 <!--
			 com.bjpowernode.spring包下所有的类所有的方法
			<aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.*(..))"/>
			 -->
			<aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.add*(..)) || execution(* com.bjpowernode.spring.*.del*(..))"/>
			<aop:before method="checkSecurity" pointcut-ref="addAddMethod"/>
		</aop:aspect>
	</aop:config>
</beans>
</span></span></span>

Client客户端的调用

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.bjpowernode.spring;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Client {

	public static void main(String[] args) {
		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");

		UserManagerImpl userManager = (UserManagerImpl)factory.getBean("userManager");
		userManager.addUser("张三", "123");

	}

}
</span></span></span>

最终效果

AOP两种代理的区别

Jdk基于接口实现:JDK动态代理对实现了接口的类进行代理。

  • CGLIB基于继承:CGLIB代理可以对类代理,主要对指定的类生成一个子类,因为是继承,所以目标类最好不要使用final声明。
  • 如果目标对象实现了接口,默认情况下采用JDK的动态代理实现AOP,也可以强制使用CGLB生成代理实现;
  • 如果目标对象没有实现接口,那么必须引入CGLB,spring会在JDK的动态代理和CGLB代理之间切换

通常情况下,鼓励使用jdk代理,因为业务一般都会抽象出一个接口,而且不用引入新的东西。如果是遗留的系统,以前没有实现接口,那么只能使用CGLIB。

一般情况下优先采用JDK动态代理,虽然其效率似乎比不上CGLIB代理,但是其对象用完之后可以正常释放。但是CGLIB代理每代理一个对象,都会产生一个新类。而类一旦载入JVM,按照大部分JVM的机制,这些新类占用的内存不会释放。J2EE程序一般运行时间都很长,内存上会有一些压力。

XML和AspectJ注解方式配置优缺点对比

用XML风格,则所有的切面、切点、通知等配置都写在一个或几个Spring配置文件里。这样的好处是,从配置文件中,就可以很清晰的看出系统中的有哪些切面,某个切面里使用那个的通知(advice)以及通知(advice)作用的切点。而在AspectJ风格中,在java程序中标识切面则显得凌乱、模糊。

在什么情况下使用注解形式的AOP?或者说使用注解来实现AOP有哪些优点呢?

1. XML风格的AOP仅仅支持"singleton"切面实例模型,而采用AspectJ风格的AOP则

没有这个限制。

2.XML风格的AOP中是不支持命名连接点的声明,而采用AspectJ风格的AOP则没有这个限制。不太理解的看下面实例代码:

在@AspectJ风格中我们可以编写如下的内容:

<span style="font-size:18px;">    @Pointcut(execution(* get*()))
                    public void propertyAccess() {}  

                    @Pointcut(execution(org.xyz.Account+ *(..))
                    public void operationReturningAnAccount() {}  

                    @Pointcut(propertyAccess() && operationReturningAnAccount())
                public void accountPropertyAccess() {}  </span>

在XML风格中,我们不能使用‘&&‘字符来连接命名连接点,如下:

<span style="font-size:18px;">    <aop:pointcut id="propertyAccess"
                    expression="execution(* get*())"/>  

                    <aop:pointcut id="operationReturningAnAccount"
                expression="execution(org.xyz.Account+ *(..))"/>
                <!-- 错误的配置  -->
              <aop:pointcut id="accountPropertyAccess"
                expression="propertyAccess && operationReturningAnAccount"/>  </span>

注意: XML风格AOP虽然不支命名连接点的声明,但是,可以使用如下形式处理,如下配置:

<span style="font-size:18px;">    <aop:pointcut id="propertyAccess"
                    expression="execution(* get*())"/>
       <aop:pointcut id="operationReturningAnAccount"
                expression="execution(org.xyz.Account+ *(..))"/>
        <aop:pointcut id="accountPropertyAccess"
                expression="execution(* get*()) and execution(org.xyz.Account+ *(..))"/>  </span>

总结

这两种方法都实现了AOP,提高了我们的程序代码复用率,很好的体现了抽象带来的好处,两者相互补充,相互借鉴,我们根据实际情况适当的选取和决策,在系统开发环境下适合开发的流程才是最重要的,

实践中,更加深入的体会吧ing

SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)

时间: 07-06

SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)的相关文章

SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP

AOP(Aspect Oriented Programming).是面向切面编程的技术.AOP基于IoC基础.是对OOP的故意补充. AOP之所以能得到广泛应用,主要是由于它将应用系统拆分分了2个部分:核心业务逻辑(Core business concerns)及横向的通用逻辑,也就是所谓的切面Crosscutting enterprise concerns.比如,全部大中型应用都要涉及到的持久化管理(Persistent).事务管理(Transaction Management).权限管理(P

SSH深度历险(八) 剖析SSH核心原理+Spring依赖注入的三种方式

在java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中.依赖注入的另一种说法是"控制反转",通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做. Spring依赖注入(

SSH深度历险(七) 剖析SSH核心原理(一)

接触SSH有一段时间了,但是对于其原理,之前说不出来莫模模糊糊(不能使用自己的语言描述出来的就是没有掌握),在视频和GXPT学习,主要是实现了代码,一些原理性的内容还是欠缺的,这几天我自己也一直在反问着自己,学习本不应该是这个样子了,道理倘若不懂:就是常说的老牛只知道低头拉磨,不抬头看路,映射到学习中,如果我们只是一味的写代码,而不懂原理的话,这样的生命力是不持久的,是短暂的,后劲会很不足,反问的学习促使我对这些逐步的深入了思考,参考了很多的网友博客与PDF资料,自己感悟而成,现和大家分享. 首

Java深度历险(一) Jboss+EJB的第一个实例

学习感悟:每次学习新的知识,都会通过第一个小的实例入手,获得成就感,经典的Hello Workd实例奠定了我们成功的大门哈,这些经典的实例虽小但是五脏俱全呢,很好的理解了,Ejb的核心. 今天主要以这个小实例,来学习EJB的分布式,我们可以将接口与实现放到一台计算机上,而客户端可以放到另一台机器上,当然分布式的意思很大了(下篇博客给大家讲解),快来看实例. 一:代码实现 1:定义接口 <span style="font-size:18px;"><span style=

SSH深度历险(六) 深入浅出----- Spring事务配置的五种方式

这对时间在学习SSH中Spring架构,Spring的事务配置做了具体总结.在此之间对Spring的事务配置仅仅是停留在听说的阶段,总结一下.总体把控.通过这次的学习发觉Spring的事务配置仅仅要把思路理清,还是比較好掌握的. 总结例如以下: Spring配置文件里关于事务配置总是由三个组成部分,各自是DataSource.TransactionManager和代理机制这三部分.不管哪种配置方式.一般变化的仅仅是代理机制这部分. DataSource.TransactionManager这两部

AOP实现日志打印 基于xml配置的AOP实现 切入点表达式

前置通知,后置通知,异常通知,返回通知 使用注解需要加入 在xml中加入  <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 环绕通知(跟以上结果一样)  需要有返回值return rs: 基于xml配置的AOP实现(上面的注解全去掉,配置以下) ①切入点表达式的语法格式[参见第5章AOP细节] execution([权限修饰符] [返回值类型] [简单类名/全类名] [方法名]([参数列表])) 参见第5章AOP细节:演示验证 1.任

SSH深度历险(一)深入浅出Hibernate架构(一)-------映射解析——七种映射关系

        ORM.全称是(Object Relational Mapping),即对象关系映射.ORM的实现思想就是将关系数据库中表的数据映射成对象.以对象的形式展现.这样开发者就能够把对数据库的操作转化为对这些对象的操作.Hibernate正是实现了这样的思想,达到了方便开发者以面向对象的思想来实现对数据库的操作.    Hibernate在实现ORM功能的时候主要用到的文件有:映射类(*.java).映射文件(*.hbm.xml)和数据库配置文件(*.properties/*.cfg.

day39-Spring 11-Spring的AOP:基于AspectJ的XML配置方式

Spring Aop实例之xml配置

上篇博文<3幅图让你了解Spring AOP>中介绍了aop通知类型,AOP的配置方式有2种方式:xml配置和AspectJ注解方式.今天我们就来实践一下xml配置方式. http://blog.csdn.net/xiaoxian8023/article/details/17258933 我采用的jdk代理,所以首先将接口和实现类代码附上 [java] view plaincopy package com.tgb.aop; public interface UserManager { publ

spring相关—AOP编程—数学计算器情景示例讲解(包含注解配置AOP与XML配置AOP)

1.数学计算器 ①数学计算器接口[MathCalculator]            public void add(int i,int j);     public int sub(int i,int j);     public int multi(int i,int j);     public void divide(int i,int j);    ②提供简单实现:加减乘除运算[EasyImpl]    ③在简单实现的基础上让每一个计算方法都能够打印日志[LoginImpl]