大家好,又见面了,我是你们的朋友全栈君。
Aspect Oriented Programming(AOP) “面向切面编程”。 在Spring中提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务 (例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。 主要功能 日志记录,性能统计,安全控制,事务处理,异常处理等等 通过动态代理,可以在不修改源码的前提下,实现功能的注入
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>groupId</groupId>
<artifactId>dome03</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<!--基于子类的动态代理 t2的测试类使用-->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
</dependencies>
</project>
UserDao.java
package com.xbj.dao;
/** * @Author:晓宇码匠 * @Date:2019/6/15 0015 */
public interface UserDao {
void addUser();
void delUser();
}
UserDaoImpl.java
package com.xbj.dao.impl;
import com.xbj.dao.UserDao;
/** * @Author:晓宇码匠 * @Date:2019/6/15 0015 */
public class UserDAOImpl implements UserDao {
public void addUser() {
System.out.println("addUser");
}
public void delUser() {
System.out.println("delUser");
}
//定义初始化方法
public void myInit(){
System.out.println("init...");
}
//定义销毁方法
public void dest(){
System.out.println("dest...");
}
}
MyAdvice.java
package com.xbj;
/** * @Author:晓宇码匠 * @Date:2019/6/15 0015 */
public class MyAdvice {
//通知
public void before(){
System.out.println("开启事务");
}
public void after(){
System.out.println("关闭事务");
}
}
test测试类:
import com.xbj.MyAdvice;
import com.xbj.dao.UserDao;
import com.xbj.dao.impl.UserDAOImpl;
import org.junit.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/** * @Author:晓宇码匠 * @Date:2019/6/15 0015 */
public class test {
@Test
public void t1(){
//目标类
final UserDAOImpl userDAO = new UserDAOImpl();
//通知(植入的功能)
final MyAdvice advice = new MyAdvice();
InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.equals("delUser")){
advice.before();
}
Object object=method.invoke(userDAO,args);
if (method.getName().equals("addUser")){
advice.after();
}
return object;
}
};
//Proxy.newProxyInstance(类加载器, 接口ming.,回调函数;
UserDao proxyClass = (UserDao) Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(),handler);
proxyClass.addUser();
System.out.println("------------------");
proxyClass.delUser();
}
}
控制台输出:
addUser
关闭事务
------------------
delUser
代码同上 test测试类添加了t2测试方法:
import com.xbj.MyAdvice;
import com.xbj.dao.UserDao;
import com.xbj.dao.impl.UserDAOImpl;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/** * @Author:晓宇码匠 * @Date:2019/6/15 0015 */
public class test {
@Test
public void t1(){
//目标类
final UserDAOImpl userDAO = new UserDAOImpl();
//通知(植入的功能)
final MyAdvice advice = new MyAdvice();
InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.equals("delUser")){
advice.before();
}
Object object=method.invoke(userDAO,args);
if (method.getName().equals("addUser")){
advice.after();
}
return object;
}
};
//Proxy.newProxyInstance(类加载器, 接口ming.,回调函数;
UserDao proxyClass = (UserDao) Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(),handler);
proxyClass.addUser();
System.out.println("------------------");
proxyClass.delUser();
}
@Test
public void t2(){
//目标类
final UserDAOImpl userDAOimpl=new UserDAOImpl();
//通知(植入的功能)
final MyAdvice advice=new MyAdvice();
Callback callback=new MethodInterceptor() {
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
advice.before();
Object obj=method.invoke(userDAOimpl,objects);
advice.after();
return obj;
}
};
//superclass callback
UserDao proxyClass= (UserDao) Enhancer.create(userDAOimpl.getClass(),callback);
proxyClass.delUser();
}
}
运行t2测试方法,控制台输出:
开启事务
delUser
关闭事务
@Component @Controller @Repository @Service 都是将bean放入Ioc容器中,只是为了代码的可读性而去区别开 @Autowired 是从Ioc容器拿对象
流程:
<!--1. 扫描:发现Bean 哪里的Bean你想被我管理-->
<!--2. 在被扫描的目录去做标注,哪些具体的类要被管理-->
<!--3.配置AOP 动态代理
1. 哪里增强(切入点)
2. 增强什么(advice)-->
<!-- 4.切入点:方法 void 包.类.方法(args) -->
applicationContext.xml
<?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/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<context:component-scan base-package="com.xbj"/>
<!--配置 自动代理-->
<aop:config proxy-target-class="true">
<!--<aop:pointcut id="myPointcut" expression="execution(* com.xbj.service.impl.*.*(..))" />-->
<!--<aop:advisor advice-ref="myAspect" pointcut-ref="myPointcut" />-->
<aop:advisor advice-ref="myAspect" pointcut="execution(* com.xbj.service.impl.*.*(..))" />
</aop:config>
</beans>
UserController.java
package com.xbj.controller;
import com.xbj.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/** * @Author:晓宇码匠 * @Date:2019/6/15 0015 */
/* @Controller @Repository @Component @Service 都是将bean放入Ioc容器中,只是为了代码的可读性而去区别开 * @Autowired 是从Ioc容器拿对象 * */
@Controller
public class UserController {
@Autowired
private UserService userService;
public void addUser(){
userService.addUser();
}
}
UserDao.java
package com.xbj.dao;
/** * @Author:晓宇码匠 * @Date:2019/6/15 0015 */
public interface UserDao {
void addUser();
void delUser();
}
UserDaoImpl.java
package com.xbj.dao.impl;
import com.xbj.dao.UserDao;
import org.junit.runner.RunWith;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
/** * @Author:晓宇码匠 * @Date:2019/6/15 0015 */
@Repository
public class UserDaoImpl implements UserDao {
public void addUser() {
System.out.println("addUser");
}
public void delUser() {
System.out.println("delUser");
}
//定义初始化方法
public void myInit(){
System.out.println("init...");
}
//定义销毁方法
public void dest(){
System.out.println("dest...");
}
}
UserService.java
package com.xbj.service;
/** * @Author:晓宇码匠 * @Date:2019/6/15 0015 */
public interface UserService {
void addUser();
void delUser();
}
UserServiceImpl.java
package com.xbj.service.impl;
import com.xbj.dao.UserDao;
import com.xbj.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/** * @Author:晓宇码匠 * @Date:2019/6/15 0015 */
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public void addUser() {
userDao.addUser();
}
public void delUser() {
userDao.delUser();
}
}
MyAspect.java
package com.xbj;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
/** * @Author:晓宇码匠 * @Date:2019/6/15 0015 */
/* * 注意包名:org.aopalliance.intercept.MethodInterceptor;MyAspect * */
//切面
@Component
public class MyAspect implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("前置增强");
Object obj=invocation.proceed(); //invocation 调用
System.out.println("后置增强");
return obj;
}
}
test.java
import com.xbj.controller.UserController;
import com.xbj.dao.UserDao;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/** * @Author:晓宇码匠 * @Date:2019/6/15 0015 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:applicationContext.xml"})
public class test {
@Autowired
private UserController controller;
@Test
public void t1() {
controller.addUser();
}
}
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/106639.html原文链接:https://javaforall.cn