一、 项目介绍
1、AOP面向切面编程基于xml配置方式–通知/增强案例
2、项目开发工具:
(1) jdk1.8.0_92 (2) IDEA-2019.3.4 (3) apache-maven-3.5.2
3、项目目录结构
二、源码
1、pom.xml
<?xml version
="1.0" encoding
="UTF-8"?>
<project xmlns
="http://maven.apache.org/POM/4.0.0" xmlns
:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi
:schemaLocation
="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion
>
<groupId>com
.sou
</groupId
>
<artifactId>spring_aop
</artifactId
>
<version>1.0-SNAPSHOT
</version
>
<packaging>war
</packaging
>
<!--单元测试
-->
<dependencies>
<dependency>
<groupId>junit
</groupId
>
<artifactId>junit
</artifactId
>
<version>4.12</version
>
<scope>test
</scope
>
</dependency
>
<!-- Spring的junit测试集成
-->
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-test
</artifactId
>
<version>4.3.16.RELEASE
</version
>
</dependency
>
<!-- spring四大核心包
-->
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-context
</artifactId
>
<version>4.3.16.RELEASE
</version
>
</dependency
>
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-core
</artifactId
>
<version>4.3.16.RELEASE
</version
>
</dependency
>
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-beans
</artifactId
>
<version>4.3.16.RELEASE
</version
>
</dependency
>
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-expression
</artifactId
>
<version>4.3.16.RELEASE
</version
>
</dependency
>
<!-- AOP依赖
-->
<dependency>
<groupId>aopalliance
</groupId
>
<artifactId>aopalliance
</artifactId
>
<version>1.0</version
>
</dependency
>
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-aop
</artifactId
>
<version>4.3.16.RELEASE
</version
>
</dependency
>
<dependency>
<groupId>org
.aspectj
</groupId
>
<artifactId>aspectjweaver
</artifactId
>
<version>1.8.9</version
>
</dependency
>
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-aspects
</artifactId
>
<version>4.3.16.RELEASE
</version
>
</dependency
>
<!-- 日志依赖
-->
<dependency>
<groupId>org
.slf4j
</groupId
>
<artifactId>slf4j
-log4j12
</artifactId
>
<version>1.7.30</version
>
</dependency
>
<dependency>
<groupId>commons
-logging
</groupId
>
<artifactId>commons
-logging
</artifactId
>
<version>1.2</version
>
</dependency
>
</dependencies
>
<!-- 配置jdk编译插件和tomcat插件
-->
<build>
<plugins>
<plugin>
<groupId>org
.apache
.maven
.plugins
</groupId
>
<artifactId>maven
-compiler
-plugin
</artifactId
>
<version>2.2</version
>
<configuration>
<source>1.8</source
>
<target>1.8</target
>
<encoding>utf
-8</encoding
>
</configuration
>
</plugin
>
<plugin>
<groupId>org
.apache
.tomcat
.maven
</groupId
>
<artifactId>tomcat7
-maven
-plugin
</artifactId
>
<version>2.2</version
>
<!--<configuration>
<
;!&ndash
;修改端口号
&ndash
;>
;
<port>8888</port
>
<
;!&ndash
;你的项目路径
&ndash
;>
;
<path>/</path
>
</configuration
>-->
</plugin
>
</plugins
>
</build
>
</project
>
2、resources中的配置文件
(1) log4j.properties(日志相关配置信息)
log4j
.rootLogger
=DEBUG
,A1
log4j
.logger
.org
.mybatis
=DEBUG
log4j
.appender
.A1
=org
.apache
.log4j
.ConsoleAppender
log4j
.appender
.A1
.layout
=org
.apache
.log4j
.PatternLayout
log4j
.appender
.A1
.layout
.ConversionPattern
=%-d
{yyyy
-MM
-dd HH
:mm
:ss
,SSS
} [%t
] [%c
]-[%p
] %m
%n
(2) applicationContext.xml(Spring实体bean配置文件)
<?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
.xsd
http
://www
.springframework
.org
/schema
/aop
http
://www
.springframework
.org
/schema
/aop
/spring
-aop
.xsd
http
://www
.springframework
.org
/schema
/context
http
://www
.springframework
.org
/schema
/context
/spring
-context
.xsd
"
>
<!-- 配置注解扫描,作用会自动扫描某包或子包下面含有
@Component的类,并作为bean来管理
-
-->
<context
:component
-scan base
-package="com.sou"/>
<!-- 确定目标xml
-->
<bean id
="userDao" class="com.sou.dao.impl.UserDaoImpl"/>
<bean id
="userService" class="com.sou.service.impl.UserServiceImpl"/>
<!-- 配置通知的bean
-->
<bean id
="myAspect" class="com.sou.aspect.MyAspect"/>
<!-- 配置切入点与切面
-->
<aop
:config
>
<!-- 配置切入点
(其实就是拦截哪些方法
)以service结尾的bean。 进行增强
-->
<aop
:pointcut id
="myPointcut" expression
="bean(*Service)"/>
<!-- 配置切面
:关联切入点和切面,要对哪些方法进行怎么样的增强。ref
: 目标到增强的类
-->
<aop
:aspect ref
="myAspect">
<!--配置前置通知
method
:该增强调用的通知类中的方法名
(MyAspect
)
pointcut
-ref
:关联的切入点
-->
<aop
:before method
="before" pointcut
-ref
="myPointcut"/>
<aop
:after
-returning method
="after" pointcut
-ref
="myPointcut" returning
="returnVal"/>
<!--异常通知、抛出通知
throwing
:配置方法中接收异常的参数的名称,必须和方法中的参数名字一致
! ! !-->
<aop
:after
-throwing method
="afterThrowing" pointcut
-ref
="myPointcut" throwing
="ex"/>
</aop
:aspect
>
<!-- 最终通知
-->
<!-- <aop
:after method
="after" pointcut
-ref
="myPointcut" />-->
</aop
:config
>
</beans
>
3、pojo(实体)层:
User.java
package com
.sou
.pojo
;
public class User {
private String name
;
private int age
;
}
4、aspect层(接入点):
package com
.sou
.aspect
;
import org
.aspectj
.lang
.JoinPoint
;
import org
.aspectj
.lang
.ProceedingJoinPoint
;
public class MyAspect {
public void before(JoinPoint joinPoint
) {
System
.out
.println("前置增强方法。。。");
System
.out
.println("增强的对象:" + joinPoint
.getTarget().getClass().getName());
System
.out
.println("增强的方法:" + joinPoint
.getSignature().getName());
if ("find".equals(joinPoint
.getSignature().getName())) {
throw new RuntimeException("当前用户没有权限执行该方法");
}
}
public void after(JoinPoint joinPoint
, Object returnVal
) {
System
.out
.println("后置增强方法。。。");
System
.out
.println("后置通知:系统日志:当前下发了短信的方法是:" + joinPoint
.getSignature().getName());
System
.out
.println("开始发短信了,短信内容:客户你好,您的余额为:" + returnVal
);
}
public Object
around(ProceedingJoinPoint proceedingJoinPoint
) throws Throwable
{
System
.out
.println("开启了事务。。。");
Object object
= proceedingJoinPoint
.proceed();
System
.out
.println("提交了事务。。。");
return object
;
}
public void
afterThrowing(JoinPoint joinPoint
, Throwable ex
) {
System
.out
.println("尊敬的管理员,发生了异常了,发生异常的类是: "
+ joinPoint
.getTarget().getClass().getSimpleName()
+ "发生异常的方法是: " + joinPoint
.getSignature().getName()
+ ",异常信息为: " + ex
.getMessage());
}
}
5、service层
UserService.java
package com
.sou
.service
;
import com
.sou
.pojo
.User
;
public interface UserService {
public User
login();
public void save();
}
6、service实现层
UserServiceImpl.java
package com
.sou
.service
.impl
;
import com
.sou
.dao
.UserDao
;
import com
.sou
.pojo
.User
;
import com
.sou
.service
.UserService
;
import javax
.annotation
.Resource
;
public class UserServiceImpl implements UserService {
@Resource(name
= "userDao")
private UserDao userDao
;
@Override
public User
login() {
System
.out
.println("这是UserServiceImpl的登录方法");
userDao
.login();
return null
;
}
@Override
public void save() {
System
.out
.println("业务层:添加商品异常");
int a
= 1 / 0;
}
}
7、dao层(此中只写了简单输出语句,没与数据库交互)
UserDao.java
package com
.sou
.dao
;
import com
.sou
.pojo
.User
;
public interface UserDao {
public User
login();
}
8、dao实现层
UserDaoImpl.java
package com
.sou
.dao
.impl
;
import com
.sou
.dao
.UserDao
;
import com
.sou
.pojo
.User
;
public class UserDaoImpl implements UserDao {
@Override
public User
login() {
System
.out
.println("这是UserDaoImpl登录方法");
return null
;
}
}
9、UserTest文件
SpringAopTest.java
import com
.sou
.service
.UserService
;
import org
.junit
.Test
;
import org
.junit
.runner
.RunWith
;
import org
.springframework
.test
.context
.ContextConfiguration
;
import org
.springframework
.test
.context
.junit4
.SpringJUnit4ClassRunner
;
import javax
.annotation
.Resource
;
@RunWith(SpringJUnit4ClassRunner
.class)
@ContextConfiguration(locations
= "classpath:applicationContext.xml")
public class SpringAopTest {
@Resource(name
= "userService")
private UserService userService
;
@Test
public void SpringAopTest() {
userService
.login();
userService
.save();
}
}
10、运行截图
源码,以及导入项目到自己的idea中,可以地下评论留下QQ号,看到后会及时回复,也可以加qq群:586012641 交流,谢谢