AOP(aspect oriented programming)面向切面编程。

大致意思是在方法的执行过程中织入其他要执行的方法。

项目结构图

先介绍一下通过代理的方式实现aop,几个文件和上一篇一样,再贴一遍方便观看

package com.ouc.wkp.model;

public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

User.java

package com.ouc.wkp.dao;

import com.ouc.wkp.model.User;

public interface UserDAO {
public void save(User user);
public void delete();
}

UserDAO.java

package com.ouc.wkp.dao.impl;

import org.springframework.stereotype.Component;

import com.ouc.wkp.dao.UserDAO;
import com.ouc.wkp.model.User; @Component("u")
public class UserDAOImpl implements UserDAO { @Override
public void save(User user) {
// Hibernate
// JDBC
// XML
// NetWork
System.out.println("user saved!");
// throw new RuntimeException();
} @Override
public void delete() {
// TODO Auto-generated method stub } }

UserDAOImpl.java

package com.ouc.wkp.service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component; import com.ouc.wkp.dao.UserDAO;
import com.ouc.wkp.model.User; @Component("userService")
public class UserService { private UserDAO userDAO; @PostConstruct
public void init() {
System.out.println("init");
} public void add(User user) {
userDAO.save(user);
} public UserDAO getUserDAO() {
return userDAO;
} // @Autowired @Qualifier("u")
@Resource(name = "u")
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
} @PreDestroy
public void destroy() {
System.out.println("destroy");
}
}

UserService.java

然后是一个代理类,继承自InvocationHandler

package com.ouc.wkp.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class LogIntercepter implements InvocationHandler{
private Object target; public Object getTarget() {
return target;
} public void setTarget(Object target) {
this.target = target;
} public void beforeMethod(Method m){
System.out.println(m.getName()+" start");
} public void afterMethod(Method m){
System.out.println(m.getName()+" end");
} public Object invoke(Object proxy,Method m,Object[] args) throws Throwable{
beforeMethod(m);
m.invoke(target, args);
afterMethod(m);
return null;
}
}

LogIntercepter.java

然后再测试类中进行如下调用

@Test
public void testProxy() {
UserDAO userDAO = new UserDAOImpl();
LogIntercepter li = new LogIntercepter();
li.setTarget(userDAO);
UserDAO userDAOProxy = (UserDAO) Proxy.newProxyInstance(userDAO
.getClass().getClassLoader(), userDAO.getClass()
.getInterfaces(), li);
System.out.println(userDAOProxy.getClass());
userDAOProxy.delete();
userDAOProxy.save(new User());
}

UserServiceTest.java

运行结果

然后介绍通过xml配置文件实现aop

使用aop需要一下 
 xmlns:aop="http://www.springframework.org/schema/aop" 
 http://www.springframework.org/schema/aop -->
 http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 
 <aop:aspectj-autoproxy />

还需要这个开启对com.ouc.wkp包下面的扫描

<context:component-scan base-package="com.ouc.wkp"></context:component-scan>

<?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: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.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<context:annotation-config />
<!-- 使用注解需要下面四条 -->
<!-- xmlns:context="http://www.springframework.org/schema/context" -->
<!-- http://www.springframework.org/schema/context -->
<!-- http://www.springframework.org/schema/context/spring-context-3.1.xsd"> -->
<!-- <context:annotation-config /> --> <!-- 使用aop需要一下 -->
<!-- xmlns:aop="http://www.springframework.org/schema/aop" -->
<!-- http://www.springframework.org/schema/aop -->
<!-- http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> -->
<!-- <aop:aspectj-autoproxy /> --> <!-- 扫描 -->
<context:component-scan base-package="com.ouc.wkp"></context:component-scan> <aop:aspectj-autoproxy /> <bean id="logIntercepter2" class="com.ouc.wkp.aop.LogIntercepter2"></bean>
<aop:config>
<!-- <aop:pointcut expression="execution(public * com.ouc.wkp.service..*.add(..))"
id="servicePointcut"/> -->
<!-- <aop:aspect id="logAspect" ref="logIntercepter"> -->
<!-- <aop:before method="before" pointcut="servicePointcut"/> -->
<!-- </aop:aspect> -->
<aop:aspect id="logAspect" ref="logIntercepter2">
<aop:before method="before"
pointcut="execution(public * com.ouc.wkp.service..*.add(..))" />
</aop:aspect>
</aop:config>
</beans>

beans.xml

<bean id="logIntercepter2" class="com.ouc.wkp.aop.LogIntercepter2"></bean>
<aop:config>
<!-- <aop:pointcut expression="execution(public * com.ouc.wkp.service..*.add(..))"
id="servicePointcut"/> -->
<!-- <aop:aspect id="logAspect" ref="logIntercepter"> -->
<!-- <aop:before method="before" pointcut="servicePointcut"/> -->
<!-- </aop:aspect> -->
<aop:aspect id="logAspect" ref="logIntercepter2">
<aop:before method="before"
pointcut="execution(public * com.ouc.wkp.service..*.add(..))" />
</aop:aspect>
</aop:config>

看下面这段 第一行声明了一个代理切入类(表达不准确)

<aop:pointcut expression="execution(public * com.ouc.wkp.service..*.add(..))" 
id="servicePointcut"/>标识定义一个切入点pointcut。

<aop:before method="before" pointcut="servicePointcut"/>表示before织入这个切入点。

execution(public * com.ouc.wkp.service..*.add(..))代表com.ouc.wkp.service包下的任意包的任意类的add方法。

然后我们看代理切入类

package com.ouc.wkp.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component; @Aspect
@Component
public class LogIntercepter2 {
// @Pointcut("execution(public * com.ouc.wkp.service..*.add(..))")
public void myMethod(){}; // @Before("myMethod()")
public void before() {
System.out.println("method before");
} // @AfterReturning("execution(public * com.ouc.wkp.dao..*.*(..))")
public void afterReturning(){
System.out.println("method after returning");
} // @AfterThrowing("myMethod()")
public void afterThrowing(){
System.out.println("method after throwing");
} // @Around("myMethod()")
public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("method around start");
pjp.proceed();
System.out.println("method around end");
}
}

LogIntercepter2.java

类的开头需要加上

@Aspect
@Component

测试方法

@Test
public void testAdd() throws Exception {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
"beans.xml"); UserService service = (UserService) ctx.getBean("userService");
User user = new User();
user.setUsername("qqq");
user.setPassword("123ppp");
//是一个代理
System.out.println(service.getClass());
service.add(user); ctx.destroy(); }

UserServiceTest.java

运行结果

我们看到我们获得的userservice实质上是一个代理类

最后介绍通过注解实现aop,LogIntercepter2的代码再贴一遍.

beans.xml里面的<aop:config>可以注释掉

package com.ouc.wkp.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component; @Aspect
@Component
public class LogIntercepter2 {
@Pointcut("execution(public * com.ouc.wkp.service..*.add(..))")
public void myMethod(){}; @Before("myMethod()")
public void before() {
System.out.println("method before");
} @AfterReturning("execution(public * com.ouc.wkp.dao..*.*(..))")
public void afterReturning(){
System.out.println("method after returning");
} @AfterThrowing("myMethod()")
public void afterThrowing(){
System.out.println("method after throwing");
} @Around("myMethod()")
public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("method around start");
pjp.proceed();
System.out.println("method around end");
}
}

LogIntercepter2.java

@Pointcut("execution(public * com.ouc.wkp.service..*.add(..))")

public void myMethod(){};表示定义一个切入点

@Before("myMethod()")表示在方法执行前执行注解下面的方法  myMethod()为上面定义的切入点

后面的注解见名知意

运行结果

感觉还是很神奇的 以前一直不理解什么是面向切面。现在简单了解了一下觉得很有趣,但是还是无法用语言准确表达出来= =

下一篇介绍spring整合hibernate

spring AOP简单入门的更多相关文章

  1. Spring AOP 简单入门笔记 (转)

    分享一个自己写的最为简单的Spring AOP的应用,其实,本人也是学习Spring不久,只是把一些个人的理解分享下,供参考.可能很多人刚开始不太理解到底啥是AOP,其实它也是相对 OOP来说的,类似 ...

  2. Spring AOP初级——入门及简单应用

      在上一篇<关于日志打印的几点建议以及非最佳实践>的末尾提到了日志打印更为高级的一种方式——利用Spring AOP.在打印日志时,通常都会在业务逻辑代码中插入日志打印的语句,这实际上是 ...

  3. [Spring框架]Spring AOP基础入门总结一.

    前言:前面已经有两篇文章讲了Spring IOC/DI 以及 使用xml和注解两种方法开发的案例, 下面就来梳理一下Spring的另一核心AOP. 一, 什么是AOP 在软件业,AOP为Aspect ...

  4. [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.

    前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...

  5. spring security 简单入门

    spring security 简单入门示例 一.概述 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架 . 其中最主要的安全操作有两 ...

  6. Spring Aop(二)——基于Aspectj注解的Spring Aop简单实现

    转发地址:https://www.iteye.com/blog/elim-2394762 2 基于Aspectj注解的Spring Aop简单实现 Spring Aop是基于Aop框架Aspectj实 ...

  7. Spring.Net 简单入门学习

    Spring.NET IoC容器的用法. 通过简单的例子学习Spring.Net 1.先创建一个控制台程序项目. 2.添加IUserInfoDal 接口. namespace Spring.Net { ...

  8. Spring aop 简单示例

    简单的记录一下spring aop的一个示例 基于两种配置方式: 基于xml配置 基于注解配置 这个例子是模拟对数据库的更改操作添加事物 其实并没有添加,只是简单的输出了一下记录 首先看下整个例子的目 ...

  9. Spring AOP 知识点入门

    一.基本知识点 1.AOP概念 AOP(Aspect-Oriented Programming), 即 面向切面编程, 它与 OOP( Object-Oriented Programming, 面向对 ...

随机推荐

  1. row_number() over (partition by....order by...)用法 分组排序

    row_number() over (partition by....order by...)用法 分组排序 row_number() OVER (PARTITION BY COL1 ORDER BY ...

  2. 将Python代码嵌入C++程序进行编写

    将Python代码嵌入C++程序进行编写的实例,python嵌入 把python嵌入的C++里面需要做一些步骤 安装python程序,这样才能使用python的头文件和库 在我们写的源文件中增加“Py ...

  3. [Leetcode][Python]22: Generate Parentheses

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 22: Generate Parentheseshttps://oj.leet ...

  4. CF Codeforces Round #258 (Div. 2) B (451B)

    题意:找出一段逆序! 预存a[]数组到b[]数组.将b排序,然后前后找不同找到区间[l,r],然后推断[l,r]是否逆序就能够了!.当然还得特判本身就是顺序的!! ! AC代码例如以下: #inclu ...

  5. Swift与Objective-C交互

    在同一个工程中是可以同时使用Swift和OC的,但不可以同时出现在同一个文件中. OC调用Swift相关信息的方法 在***.m文件中导入工程名-Swift.h即可. 如工程名为ABC,则在需要使用S ...

  6. 第十七周oj刷题——Problem B: 分数类的四则运算【C++】

    Description 编写分数类Fraction,实现两个分数的加.减.乘和除四则运算.主函数已给定. Input 每行四个数,分别表示两个分数的分子和分母,以0 0 0 0 表示结束. Outpu ...

  7. go-vim配置

    一.环境准备: 系统环境说明: [root@docker golang]# cat /etc/redhat-release CentOS Linux release (Core) [root@dock ...

  8. 引入css ,使用@import和link的方式

    我们也经常听到有人说要使用link来引入CSS更好,但是你知道为什么吗? 继续往下看 linklink就是把外部CSS与网页连接起来. @importimport文字上与link的区别就是它可以把在一 ...

  9. ToolStripMenuItem控件实现DatagridView行的上下移

    /*--------------行上移------------------*/ 1 private void 上移ToolStripMenuItem_Click(object sender, Even ...

  10. 【译】html5游戏入门

    [译]html5游戏入门 原文链接 简介 如果你想用canvas做个游戏,那么来对地方了. 但是但是你至少知道javascript怎么拼写(╯‵□′)╯︵┻━┻ 既然没问题,那先来玩一下或者下载 创建 ...