第三章 AOP 基于@AspectJ的AOP
在前面,我们分别使用Pointcut、Advice、Advisor接口来描述切点、增强、切面。而现在我们使用@AdpectJ注解来描述。
在下面的例子中,我们是使用Spring自动扫描和管理Bean。
(http://blog.csdn.net/p_3er/article/details/9239605)
3.6.1一个简单的例子
@Repository
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("保存用户...");
} public void delete() {
System.out.println("删除用户...");
}
}
b、通过一个
POJO使用
@AspectJ管理切面
/*
* 通过@Aspect把这个类标识管理一些切面
*/
@Aspect
@Component
public class FirstAspect { /*
* 定义切点及增强类型
*/
@Before("execution(* save(..))")
public void before(){
System.out.println("我是前置增强...");
}
}
c、配置
配置的时候要引入aop命名空间及打开@AspectJ切面驱动器
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="cn.framelife.spring"></context:component-scan>
<!—
驱动器自动为Spring容器中那些匹配@AspectJ切面的Bean创建代理,完成切面积入
-->
<aop:aspectj-autoproxy/>
d、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserDao userDao = (UserDao) context.getBean("userDaoImpl");
userDao.save();
userDao.delete();
e、结果
我是前置增强...
保存用户...
删除用户...
3.6.2增强类型及其使用
@Before前置增强
@Before(value= "切入点表达式或命名切入点",argNames = "指定命名切入点方法参数列表参数名字,可以有多个用“,”分隔")
3.6.1中的增强使用:@Before(value="execution(*save(..))")是缺省了value,直接键入值。
a、目标类
@Service
public class UserService {
public void say(String name){
System.out.println("service say:"+name);
} public void run(String way){
System.out.println("service run:"+way);
}
}
b、通过一个
POJO使用
@AspectJ管理切面
@Aspect
@Component
public class BeforAspectj { /*
*单独配置切点。给切点命名。
*/
@Pointcut(value="execution(* say(..)) && args(param)",argNames="param")
public void beforePointcut(String param){ } @Before(value="beforePointcut(s)",argNames="s")
public void beforeAdvice(String s){
System.out.println("beforeAdvice:"+s);
}
}
@Aspect
@Component
public class BeforAspectj {
@Before(value="execution(* say(..)) && args(s)",argNames="s")
public void beforeAdvice(String s){
System.out.println("beforeAdvice:"+s);
}
}
c、配置和3.6.1中一样
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
d、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserService service = (UserService) context.getBean("userService");
service.say("zhangsan");
service.run("street");
e、结果
beforeAdvice:zhangsan
service say:zhangsan
service run:street
@AfterReturning后置增强
@AfterReturning(
value="切入点表达式或命名切入点",
pointcut="切入点表达式或命名切入点",
argNames="参数列表参数名",
returning="目标对象的返回值")
pointcut与value是一样的。如果使用pointcut来声明,那么前面声明的value就没用了。
a、目标类
@Service
public class UserService {
public void say(String name){
System.out.println("service say:"+name);
} public void run(String way){
System.out.println("service run:"+way);
} public String getName(String name){
System.out.println("service getName:"+name);
return "MR"+name;
}
}
b、通过一个
POJO使用
@AspectJ管理切面
@Aspect
@Component
public class AfterReturningAspectj {
/*
* 即获取返回值,又获取传入的参数
*/
@AfterReturning(
value="execution(* cn.framelife.spring..*.getName(..)) && args(sname)",
returning="name",
argNames="name,sname")
public void afterGetNameAdvice(Object object,String sname){
System.out.println("afterGetNameAdvice:"+ (String)object+"--"+sname);
} /*
* 只要增强,返回值和参数都不理会
*/
@AfterReturning(value="execution(* cn.framelife.spring..*.run(..))")
public void afterRunAdvice(){
System.out.println("afterRunAdvice");
}
}
c、配置和3.6.1中一样
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
d、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserService service = (UserService) context.getBean("userService ");
service.getName("zhangsan");
service.run("street");
e、结果
servicegetName:zhangsan
afterGetNameAdvice:MRzhangsan--zhangsan
servicerun:steet
afterRunAdvice
@AfterThrowing异常抛出增强、@After Final增强
@AfterThrowing(
value="切入点表达式或命名切入点",
pointcut="切入点表达式或命名切入点",
argNames="参数列表参数名",
throwing="异常对应参数名")
@After( value="切入点表达式或命名切入点",argNames="参数列表参数名")
@After不管是抛出异常或者是正常退出,该增强都会执行。相当于try-catch-final里的final代码块。
a、目标类
@Service
public class UserService {
public void tryThrow(){
System.out.println("service tryThrow");
throw new RuntimeException("i am a runtime exception");
}
}
b、通过一个
POJO使用
@AspectJ管理切面
@Aspect
@Component
public class ThrowAspectj {
@AfterThrowing(value="execution(* cn.framelife.spring..tryThrow(..))",
throwing="exception",
argNames="exception")
public void afterThrowAdvisor(Exception exception){
System.out.println("afterThrowAdvisor:"+exception.getMessage());
} @After(value="execution(* cn.framelife.spring..tryThrow(..))")
public void finalThrowAdvisor(){
System.out.println("finalThrowAdvisor");
}
}
c、配置和3.6.1中一样
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
d、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserService service = (UserService) context.getBean("userService ");
service.tryThrow();
e、结果
servicetryThrow
afterThrowAdvisor:iam a runtime exception
finalThrowAdvisor
Exceptionin thread "main" java.lang.RuntimeException:i am a runtime exception
@Around环绕增强
@Around( value="切入点表达式或命名切入点",argNames="参数列表参数名")
a、目标类
@Service
public class UserService {
public void round(){
System.out.println("service round");
} public void run(String way){
System.out.println("service run:"+way);
} public String getName(String name){
System.out.println("service getName:"+name);
return "MR"+name;
}
}
b、通过一个
POJO使用
@AspectJ管理切面
@Aspect
@Component
public class AroundAspect { @Around(value="execution(* cn.framelife.spring..round(..))")
public Object aroundAdvisor(ProceedingJoinPoint point) throws Throwable{
System.out.println("before method");
Object target = point.proceed();
System.out.println("after method");
return target;
}
}
c、配置和3.6.1中一样
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
d、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserService service = (UserService) context.getBean("userService");
service.round();
service.run("street");
e、结果
beforemethod
serviceround
aftermethod
servicerun:street
afterRunAdvice
@DeclareParents引介增强
@DeclareParents(
value="AspectJ语法类型表达式",
defaultImpl=引入接口的默认实现类)
下面的例子是Waiter为目标类,然后让目标类拥有ISeller接口的功能:
a、两个接口与两个类
目标类与其接口:
public interface IWaiter {
public void service();
}
@Component
public class Waiter implements IWaiter {
@Override
public void service() {
System.out.println("service");
}
}
运行期织入到目标类的功能类与其接口:
public interface ISeller {
public void sell();
}
public class Seller implements ISeller {
@Override
public void sell() {
System.out.println("sell");
}
}
POJO使用
@AspectJ管理切面
@Aspect
@Component
public class DeclareAspect { /*
* value里面配置目标类
* defaultImpl是功能类的实现类
*/
@DeclareParents(
value="cn.framelife.spring.aspectj.Waiter",
defaultImpl=Seller.class)
private ISeller seller; //使用功能类接口声明一个对象
}
c、配置和3.6.1中一样
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
d、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
IWaiter waiter = (IWaiter) context.getBean("waiter");
waiter.service();
ISeller seller = (ISeller)waiter;
seller.sell();
e、结果
service
sell
3.6.3切点函数
带@开头的函数都是针对注解类的。而不带@的函数是针对普通类的。
execution()
execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>)<异常模式>?)
除了返回类型模式、方法名模式和参数模式外,其它都是可选的。
1)通过方法签名定义切点
execution(public* *(..))
匹配所有目标类的public方法,但不匹配SmartSeller和protectedvoid showGoods()方法。第一个*代表返回类型,第二个*代表方法名,而..代表任意入参的方法;
execution(* *To(..))
匹配目标类所有以To为后缀的方法。它匹配NaiveWaiter和NaughtyWaiter的greetTo()和serveTo()方法。第一个*代表返回类型,而*To代表任意以To为后缀的方法;
2)通过类定义切点
execution(*com.baobaotao.Waiter.*(..))
匹配Waiter接口的所有方法,它匹配NaiveWaiter和NaughtyWaiter类的greetTo()和serveTo()方法。第一个*代表返回任意类型,com.baobaotao.Waiter.*代表Waiter接口中的所有方法;
execution(*com.baobaotao.Waiter+.*(..))
匹配Waiter接口及其所有实现类的方法,它不但匹配NaiveWaiter和NaughtyWaiter类的greetTo()和serveTo()这两个Waiter接口定义的方法,同时还匹配NaiveWaiter#smile()和NaughtyWaiter#joke()这两个不在Waiter接口中定义的方法。
3)通过类包定义切点
在类名模式串中,“.*”表示包下的所有类,而“..*”表示包、子孙包下的所有类。
execution(*com.baobaotao.*(..))
匹配com.baobaotao包下所有类的所有方法;
execution(*com.baobaotao..*(..))
匹配com.baobaotao包、子孙包下所有类的所有方法,如com.baobaotao.dao,com.baobaotao.servier以及com.baobaotao.dao.user包下的所有类的所有方法都匹配。“..”出现在类名中时,后面必须跟“*”,表示包、子孙包下的所有类;
execution(*com..*.*Dao.find*(..))
匹配包名前缀为com的任何包下类名后缀为Dao的方法,方法名必须以find为前缀。如com.baobaotao.UserDao#findByUserId()、com.baobaotao.dao.ForumDao#findById()的方法都匹配切点。
4)通过方法入参定义切点
切点表达式中方法入参部分比较复杂,可以使用“*”和“..”通配符,其中“*”表示任意类型的参数,而“..”表示任意类型参数且参数个数不限。
execution(*joke(String,int)))
匹配joke(String,int)方法,且joke()方法的第一个入参是String,第二个入参是int。它匹配NaughtyWaiter#joke(String,int)方法。如果方法中的入参类型是java.lang包下的类,可以直接使用类名,否则必须使用全限定类名,如joke(java.util.List,int);
execution(*joke(String,*)))
匹配目标类中的joke()方法,该方法第一个入参为String,第二个入参可以是任意类型,如joke(Strings1,String s2)和joke(Strings1,double d2)都匹配,但joke(Strings1,double d2,String s3)则不匹配;
execution(*joke(String,..)))
匹配目标类中的joke()方法,该方法第一个入参为String,后面可以有任意个入参且入参类型不限,如joke(Strings1)、joke(Strings1,String s2)和joke(Strings1,double d2,String s3)都匹配。
execution(*joke(Object+)))
匹配目标类中的joke()方法,方法拥有一个入参,且入参是Object类型或该类的子类。它匹配joke(Strings1)和joke(Clientc)。如果我们定义的切点是execution(*joke(Object)),则只匹配joke(Objectobject)而不匹配joke(Stringcc)或joke(Clientc)。
args()
该函数的入参是一个类名,表示目标类的方法入参对象是指定的类(包含子类),切点匹配。它允许类后后使用+通配符后缀,但添加也不添加+效果是一样的。
例子:
public class User implements Serializable {
}
b、目标类
@Service
public class UserService {
public void say(User user){
System.out.println("say");
}
}
c、通过一个
POJO使用
@AspectJ管理切面
@Aspect
@Component
public class BeforAspectj {
@Before(value="args(cn.framelife.spring.aspectj.User)")
public void beforeAdvice(){
System.out.println("beforeAdvice");
}
}
d、配置和3.6.1中一样
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
e、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserService service = (UserService) context.getBean("userService");
service.say(new User());
f、结果
beforeAdvice
say
within()
通过类的匹配模式串声明切点。该函数定义的连接点是针对目标类(不能是接口)而言,而不是针对运行时的对象,这与execution()函数相同。Execution()所指定的连接点可以是小到参数,而within()指定的连接点最小只能是类。
within(cn.framelife.spring.aspectj.UserService)
匹配UserService类下所有的方法。
within(cn.framelife.spring.aspectj.*)
匹配cn.framelife.spring.aspectj包下所的的类,但不包括子孙包。cn.framelife.spring.aspectj.abc.AbcService是不匹配的。
within(cn.framelife.spring.aspectj..*)
匹配cn.framelife.spring.aspectj包及其子孙包下所的的类。
target()与this()
target()函数是通过判断目标类是否按类型匹配指定类决定连接点是否匹配。
target(cn.framelife.spring.aspectj.UserService)
匹配这UserService类及其子孙类的所有方法。如果UserService是一个接口,那么会匹配UserService的实现类及实现类的子孙类中的所有的方法。
this()函数是通过判断代理类是否按类型匹配指定类决定连接点是否匹配。
一般情况下,使用this()和target()定义切点,两者是等效的:
target(cn.framelife.spring.aspectj.UserService)与this(cn.framelife.spring.aspectj.UserService)是一样的。无论UserService是一个类还是一个接口。
两者区别体现在通过引介切面产生代理对象时。
@annotation()
表示标注了某个自定义注解的方法,使用切面。
@Retention(value=RetentionPolicy.RUNTIME)
@Target(value=ElementType.METHOD)
public @interface BeforeAdvisor {
boolean value() default false;
}
POJO使用
@AspectJ管理切面
@Aspect
@Component
public class BeforAspectj {
@Before(value="@annotation(cn.framelife.spring.aspectj.annotation.BeforeAdvisor)")
public void beforeAdvice(){
System.out.println("beforeAdvice");
}
}
c、配置和3.6.1中一样
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
d、目标类
@Service
public class UserService {
@BeforeAdvisor
public void annotation(){
System.out.println("annotation");
}
}
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserService service = (UserService) context.getBean("userService");
service.annotation();
f、结果
beforeAdvice
annotation
@args()
该函数的入参是一个注解类的类名,表示运行时目标类方法的入参对象的类标注了指定的注解。
@Retention(value=RetentionPolicy.RUNTIME)
@Target(value=ElementType.TYPE)
public @interface UserAnnotation {
}
b、切面管理
@Aspect
@Component
public class BeforAspectj {
@Before(value="@args(cn.framelife.spring.aspectj.annotation.UserAnnotation)")
public void beforeAdvice(){
System.out.println("beforeAdvice");
}
}
c、实体类(使用上面定义的注解)
@UserAnnotation
public class User implements Serializable {
}
d、目标类
@Service
public class UserService { public void annotation(){
System.out.println("annotation");
} public void say(User user){
System.out.println("say");
}
}
e、配置和3.6.1中一样
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
f、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
UserService service = (UserService) context.getBean("userService");
service.say(new User());
g、结果
beforeAdvice
say
@within和@target()
@winthin(A)匹配任意标注了@A的目标类。@target(A)匹配@A的类及子孙类。
@annotation是标注在目标类的方法
@args是标注目标类方法的入参对象的类
@winthin与@target是标注目标类
注意
上面的函数(特别是args())除了可以指定类名外,还可以指定参数名,将目标对象连接点上的方法入参绑定到增强的方法中。如:@Before中的例子。
3.6.4通配符与逻辑运算符
@Aspectj支持3种通配符:
*匹配任意字符,但它只能匹配上下文中的一个元素
..匹配任意字符,可以匹配上下文中的多个元素,但在表示类时,必须和*联合使用,而在表示入参时则单独使用。
+表示按类型匹配指定类及其子孙类,必须跟在类名后面。如cn.framelife.spring.UserService+表示UserService类及其子类。
函数支持:
支持所有的通配符的函数:execution()、within()
仅支持+通配符的函数:args()、this()、targ()。虽然这三个函数可以支持+通配符,但对于这些函数来说使用和不使用+都是一样的。
不支持通配符的函数:@args、@within、@target()、@annotation()。也就是所有用于注解上的函数都不支持通配符。
@Aspectj支持的逻辑运算符:
&&与
||或
!非
第三章 AOP 基于@AspectJ的AOP的更多相关文章
- 利用基于@AspectJ的AOP实现权限控制
一. AOP与@AspectJ AOP 是 Aspect Oriented Programming 的缩写,意思是面向方面的编程.我们在系统开发中可以提取出很多共性的东西作为一个 Aspect,可以理 ...
- Spring 基于 AspectJ 的 AOP 开发
Spring 基于 AspectJ 的 AOP 开发 在 Spring 的 aop 代理方式中, AspectJ 才是主流. 1. AspectJ 简介 AspectJ 是一个基于 java 语言的 ...
- spring aop 基于schema的aop
AOP的基本概念: 连接点(Jointpoint):表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化.方法执行.方法调用.字段调用或处理异常等等,Spring只支持方法执行连接点,在AOP ...
- [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.
前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...
- 开涛spring3(6.4) - AOP 之 6.4 基于@AspectJ的AOP
Spring除了支持Schema方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明. 6.4.1 启用对@AspectJ的支持 Spring默认不支持@AspectJ风格的切面声明, ...
- Spring框架学习09——基于AspectJ的AOP开发
1.基于注解开发AspectJ (1)AspectJ注解 基于注解开发AspectJ要比基于XML配置开发AspectJ便捷许多,所以在实际开发中推荐使用注解方式.关于注解的相关内容如下: @Aspe ...
- Spring AOP 基于AspectJ
简介 AspectJ是一个基于Java语言的AOP框架,Spring2.0以后新增了对AspectJ切点表达式支持.因为Spring1.0的时候Aspectj还未出现; AspectJ1.5中新增了对 ...
- 基于aspectj的aop的操作
1.引入相关的jar包 2.建两个类 public class Book { public void add(){ System.out.println("add-----------&qu ...
- Spring -- aop, 用Aspectj进行AOP开发
1. 概要 添加类库:aspectjrt.jar和aspectjweaver.jar 添加aop schema. 定义xml元素:<aop:aspectj-autoproxy> 编写jav ...
随机推荐
- 四个机器学习一步一步入门约束波尔兹曼机RBM
- ALV双击单元格事件处理
*激发双击事件 FORM f_alv_user_command USING r_ucomm LIKE sy-ucomm rs_selfield TYPE slis_selfield. "先引 ...
- 内核空间和用户空间的分界 PAGE_OFFSET
PAGE_OFFSET 首先看看PAGE_OFFSET的功能 内存映射 | 用户空间 | 内核空间 | |——————+———— ...
- 再说Java EE
说到JavaEE(曾经叫J2EE)是什么,你可能回答:JavaEE是一组规范,这么说是没错,可是自己不认为这个答案非常大.非常空么?什么又是规范?规范能组成应用么?能在JVM中跑起来么?要理解这些,先 ...
- 第二章排错的工具:调试器Windbg(下)
感谢博主 http://book.51cto.com/art/200711/59874.htm 2.2 读懂机器的语言:汇编,CPU执行指令的最小单元2.2.1 需要用汇编来排错的常见情况 汇编是 ...
- apk应用的反编译和源代码的生成
对于反编译一直持有无所谓有或无的态度.经过昨天一下午的尝试,也有了点心得和体会: 先给大家看看编译的过程和我们反编译的过程概图吧: 例如以下是反编译工具的根文件夹结构: 三个目录也实际上是下面三个步骤 ...
- C#反射Assembly 具体说明
1.对C#反射机制的理解 2.概念理解后,必须找到方法去完毕,给出管理的主要语法 3.终于给出有用的样例,反射出来dll中的方法 反射是一个程序集发现及执行的过程,通过反射能够得到*.exe或*.dl ...
- 终于懂了:TControl.Perform是有返回值的,且看VCL框架如何利用消息的返回值(全部例子都在这里)——它的存在仅仅是为了方便复用消息的返回值
代码如下: function TControl.Perform(Msg: Cardinal; WParam, LParam: Longint): Longint; var Message: TMess ...
- 用Qt开发Web和本地混合的应用
QtWebkit 模块使得Qt widget能够通过HTML的object标签嵌入到web页面中,并通过JavaScript代码进行访问,而Qt对象也能相应的访问web页面元素. 将Qt对象插入到we ...
- The usage of V$PGA_TARGET_ADVICE
Oracle 10g 给出了一系列的自动优化的建议,告诉我们PGA分配多大能给系统带来最大的性能?V$PGA_TARGET_ADVICE视图给出了很好的“预测”! 看一下这个视图能给我们带来什么样的信 ...