1.项目初始化
1.1 pom.xml
<dependencies>
<!-- spring依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- spring事务依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- mybatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!-- mybatis和spring集成依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<!-- 阿里的连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!-- aspectj-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.bundles</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.8_2</version>
</dependency>
</dependencies>
1.2UserService对象
package com.nq.service;
import org.springframework.stereotype.Component;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/29 23:04
*/
@Component
public class UserService {
public void test(){
System.out.println("test方法。");
}
public void a(){
System.out.println("a方法。");
}
}
2.cjlib动态代理的使用
2.1所有的方法都是使用动态代理
package com.nq.service;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/29 23:29
*/
public class CglibTest {
public static void main(String[] args) {
UserService target =new UserService();
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before...");
//被代理的对象,目标方法
//Object result=methodProxy.invoke(target,objects);
//Object result=method.invoke(target,objects);
Object result=methodProxy.invokeSuper(o,objects);
System.out.println("After...");
return result;
}
}
});
UserService userService = (UserService) enhancer.create();
userService.test();
}
}
2.2不同的方法使用不同的代理
package com.nq.service;
import org.springframework.cglib.proxy.*;
import java.lang.reflect.Method;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/29 23:29
*/
public class CglibTest {
public static void main(String[] args) {
UserService target =new UserService();
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before...");
//被代理的对象,目标方法
//Object result=methodProxy.invoke(target,objects);
//Object result=method.invoke(target,objects);
Object result=methodProxy.invokeSuper(o,objects);
System.out.println("After...");
return result;
}
}
, NoOp.INSTANCE});
enhancer.setCallbackFilter(new CallbackFilter() {
@Override
public int accept(Method method) {
if("test".equals(method.getName())){//表示test方法执行第一个代理方法,其他方法执行第二个方法
return 0;
}else{
return 1;
}
}
});
UserService userService = (UserService) enhancer.create();
userService.a();
}
}
3.jdk动态代理的使用
3.1UserInterface创建接口
package com.nq.service;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/29 23:58
*/
public interface UserInterface {
void test();
void a();
}
3.2UserService实现接口
package com.nq.service;
import org.springframework.stereotype.Component;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/29 23:04
*/
@Component
public class UserService implements UserInterface{
public void test(){
System.out.println("test方法。");
}
public void a(){
System.out.println("a方法。");
}
}
3.3JdkTest代理的main方法
package com.nq.service;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/29 23:56
*/
public class JdkTest {
public static void main(String[] args) {
UserInterface target=new UserService();
UserInterface userInterface =(UserInterface) Proxy.newProxyInstance(JdkTest.class.getClassLoader(), new Class[]{UserInterface.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Jdk动态代理被执行了,方法之前");
method.invoke(target,args);
System.out.println("Jdk动态代理被执行了,方法之后");
return null;
}
});
userInterface.test();
}
}
4.spring中动态代理的使用
4.1proxyFactory 动态代理的使用方法
NickelBeforeAdvice.java方法执行之前
package com.nq.advice;
import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/30 0:59
*/
public class NickelBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("方法执行前被执行了");
}
}
NickelAfterReturningAdvice.java方法执行之后
package com.nq.advice;
import org.aspectj.lang.annotation.AfterReturning;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/30 0:59
*/
public class NickelAfterReturningAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("方法returning被执行了");
}
}
NickelAroundadvice.java环绕方法
package com.nq.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/30 0:59
*/
public class NickelAroundadvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("方法执行round之前");
Object proceed = invocation.proceed();
System.out.println("方法执行round之后");
return proceed;
}
}
NickelThrowAdvice.java抛异常方法
package com.nq.advice;
import org.springframework.aop.ThrowsAdvice;
import java.lang.reflect.Method;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/30 1:00
*/
public class NickelThrowAdvice implements ThrowsAdvice {
public void afterThrowing(Method method, Object[] args, Object target, NullPointerException ex) {
System.out.println("方法抛异常执行了");
}
}
UserService.java抛异常方法
package com.nq.service;
import org.springframework.stereotype.Component;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/29 23:04
*/
@Component
public class UserService implements UserInterface{
public void test(){
System.out.println("test方法。");
}
public void a(){
System.out.println("a方法。");
throw new NullPointerException();
}
}
SpringProxtFactoryTest.java测试方法
package com.nq.service;
import com.nq.advice.NickelAfterReturningAdvice;
import com.nq.advice.NickelAroundadvice;
import com.nq.advice.NickelBeforeAdvice;
import com.nq.advice.NickelThrowAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
import java.lang.reflect.Method;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/30 0:49
*/
public class SpringProxtFactoryTest {
public static void main(String[] args) {
UserService target=new UserService();
ProxyFactory proxyFactory=new ProxyFactory();
proxyFactory.setTarget(target);
//proxyFactory.setInterfaces(UserInterface.class);这里可以指定为接口类型
proxyFactory.addAdvice(new NickelAroundadvice());
proxyFactory.addAdvice(new NickelBeforeAdvice());
UserService userService = (UserService) proxyFactory.getProxy();
userService.test();
}
}
4.2proxyFactory 对方法名字进行限制
NickelStaticMethodMatherPointcut.java方法匹配的方法
package com.nq.advice;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import java.lang.reflect.Method;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/30 1:39
*/
public class NickelStaticMethodMatherPointcut extends StaticMethodMatcherPointcut {
@Override
public boolean matches(Method method, Class<?> aClass) {
return method.getName().equals("test");
}
}
NickelPointcutAdvisor.java切面方法
package com.nq.advice;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Pointcut;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import java.lang.reflect.Method;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/30 1:34
*/
public class NickelPointcutAdvisor implements PointcutAdvisor {
@Override
public Pointcut getPointcut() {
return new NickelStaticMethodMatherPointcut();
}
@Override
public Advice getAdvice() {
return new NickelBeforeAdvice();
}
@Override
public boolean isPerInstance() {
return false;
}
}
SpringProxtFactoryTest.java测试的方法
package com.nq.service;
import com.nq.advice.*;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
import java.lang.reflect.Method;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/30 0:49
*/
public class SpringProxtFactoryTest {
public static void main(String[] args) {
UserService target=new UserService();
ProxyFactory proxyFactory=new ProxyFactory();
proxyFactory.setTarget(target);
//proxyFactory.setInterfaces(UserInterface.class);这里可以指定为接口类型
//proxyFactory.addAdvice(new NickelAroundadvice());
//proxyFactory.addAdvice(new NickelBeforeAdvice());
proxyFactory.addAdvisor(new NickelPointcutAdvisor());
UserService userService = (UserService) proxyFactory.getProxy();
userService.test();
}
}
4.3spring中的动态代理方式
4.3.1spring执行方法时候启动逻辑
UserService.java修改
package com.nq.service;
import org.springframework.stereotype.Component;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/29 23:04
*/
public class UserService{
public void test(){
System.out.println("test方法。");
}
public void a(){
System.out.println("a方法。");
//throw new NullPointerException();
}
}
说明:这里需要去掉Component注解
AppConfig.java配置
package com.nq.service;
import com.nq.advice.NickelAfterReturningAdvice;
import com.nq.advice.NickelBeforeAdvice;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/28 14:59
*/
@ComponentScan("com.nq")
public class AppConfig {
@Bean
public ProxyFactoryBean userService(){
UserService userService=new UserService();
ProxyFactoryBean proxyFactoryBean=new ProxyFactoryBean();
proxyFactoryBean.addAdvice(new NickelAfterReturningAdvice());
proxyFactoryBean.setTarget(userService);
return proxyFactoryBean;
}
}
Test.java配置
package com.nq.service;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/29 23:00
*/
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext();
context.register(AppConfig.class);
context.refresh();
UserService userService = (UserService) context.getBean("userService");
userService.test();
}
}
启动Test.java显示结果
4.3.2不去掉注解,spring执行方法的时候执行对应的逻辑
修改NickelAfterReturningAdvice.Java,增加注解
package com.nq.advice;
import org.aspectj.lang.annotation.AfterReturning;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/30 0:59
*/
@Component
public class NickelAfterReturningAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("方法returning被执行了");
}
}
修改UserService.Java,增加注解
package com.nq.service;
import org.springframework.stereotype.Component;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/29 23:04
*/
@Component
public class UserService{
public void test(){
System.out.println("test方法。");
}
public void a(){
System.out.println("a方法。");
//throw new NullPointerException();
}
}
修改AppConfig.Java配置文件
package com.nq.service;
import com.nq.advice.NickelAfterReturningAdvice;
import com.nq.advice.NickelBeforeAdvice;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/28 14:59
*/
@ComponentScan("com.nq")
public class AppConfig {
@Bean
public BeanNameAutoProxyCreator beanNameAutoProxyCreator(){
BeanNameAutoProxyCreator beanNameAutoProxyCreator=new BeanNameAutoProxyCreator();
beanNameAutoProxyCreator.setBeanNames("userSe*");
beanNameAutoProxyCreator.setInterceptorNames("nickelAfterReturningAdvice");
beanNameAutoProxyCreator.setProxyTargetClass(true);
return beanNameAutoProxyCreator;
}
}
Test.Java配置文件
package com.nq.service;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/29 23:00
*/
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext();
context.register(AppConfig.class);
context.refresh();
UserService userService = (UserService) context.getBean("userService");
userService.test();
}
}
Test测试结果
4.3.3AppConfig另外实现动态代理
package com.nq.service;
import com.nq.advice.NickelAfterReturningAdvice;
import com.nq.advice.NickelBeforeAdvice;
import org.springframework.aop.framework.DefaultAdvisorChainFactory;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.NameMatchMethodPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/28 14:59
*/
@ComponentScan("com.nq")
public class AppConfig {
@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor(){
NameMatchMethodPointcut pointcut=new NameMatchMethodPointcut();
pointcut.addMethodName("test");
DefaultPointcutAdvisor defaultPointcutAdvisor=new DefaultPointcutAdvisor();
defaultPointcutAdvisor.setPointcut(pointcut);
defaultPointcutAdvisor.setAdvice(new NickelAfterReturningAdvice());
return defaultPointcutAdvisor;
}
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
return defaultAdvisorAutoProxyCreator;
}
}
测试结果
其中DefaultAdvisorAutoProxyCreator通过导入的方式
package com.nq.service;
import com.nq.advice.NickelAfterReturningAdvice;
import com.nq.advice.NickelBeforeAdvice;
import org.springframework.aop.framework.DefaultAdvisorChainFactory;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.NameMatchMethodPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/28 14:59
*/
@ComponentScan("com.nq")
@Import(DefaultAdvisorAutoProxyCreator.class)
public class AppConfig {
@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor(){
NameMatchMethodPointcut pointcut=new NameMatchMethodPointcut();
pointcut.addMethodName("test");
DefaultPointcutAdvisor defaultPointcutAdvisor=new DefaultPointcutAdvisor();
defaultPointcutAdvisor.setPointcut(pointcut);
defaultPointcutAdvisor.setAdvice(new NickelAfterReturningAdvice());
return defaultPointcutAdvisor;
}
}
4.4spring中Aspect的使用
创建NickelAspect.java
package com.nq.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/30 2:37
*/
@Aspect
@Component
public class NickelAspect {
@Before("execution(public void com.nq.service.UserService.test())")
public void nickelBefore(JoinPoint joinPoint){
System.out.println("NickelAspect执行了");
}
}
修改AppConfig.java扫描类
package com.nq.service;
import com.nq.advice.NickelAfterReturningAdvice;
import com.nq.advice.NickelBeforeAdvice;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.aop.framework.DefaultAdvisorChainFactory;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.NameMatchMethodPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
/**
* @author Nickel
* @version 1.0
* @date 2023/7/28 14:59
*/
@ComponentScan("com.nq")
@Import(AnnotationAwareAspectJAutoProxyCreator.class)
//@EnableAspectJAutoProxy
public class AppConfig {
}
启动测试类测试