Spring-AOP的注解方式和xml方式,以及不同的代理方式(CGLIB,PROXY)

Spring-AOP

导包:

这个是使用spring所需要的必须jar包的关联依赖
    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.22.RELEASE</version>
        </dependency>
这是使用springAOP是要依赖的外部aspectj
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.2</version>
        </dependency>

使用xml方式实现动态代理

实例1:

代理对象为CGLIB ,既是没有接口的目标类实现代理

目标类  没有接口
public class Hello {
​
    public void sayHello(String  word){
        System.out.println(word);
        
    }
}
通知类 方式1使用的
public class MyAOP implements MethodBeforeAdvice{
​
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("目标方法调用之前,要开始用");
        
    }
}
通知类 方式2使用的
public class MyAOP {
​
    
    public void before(JoinPoint joinPoint){
        System.out.println("这里是前置通知,请放心使用");
        System.out.println(joinPoint.getThis().getClass());
        System.out.println(joinPoint.getArgs());
        
    }
    
    
    public void around(){
        
    }
    
    public void after(){
        System.out.println("方法执行结束啦");
    }
}
​

application.xml配置

​
通知类:
两种方式:
    <aop:config>
    
        <aop:pointcut expression="execution(* chencj.cc.aop.Hello.*(..))" id="helloT"/>
        方式1:直接使用确定的通知类接口的实现类
        MethodBeforeAdvice    AfterReturningAdvice等等
        <aop:advisor advice-ref="myAOP" pointcut-ref="helloT"/>
        
        方式2 通过<aop:aspect ref="myAOP"> 去实现,两者二选一
     <aop:aspect ref="myAOP">
           <!--;!&ndash; before | after | after-returning | after-throwing | around &ndash;-->
            <aop:before method="before" pointcut-ref="helloT"/>
            <aop:after method="after" pointcut-ref="helloT"/>
        </aop:aspect
    </aop:config>
​
目标类
<bean class="chencj.cc.aop.Hello" id="hello"></bean>
通知类
<bean class="chencj.cc.aop.MyAOP" id="myAOP"></bean>

测试

​
public class Client {
​
    public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:application.xml");
        Hello bean = applicationContext.getBean(Hello.class);//实体类的代理
        System.out.println(bean.getClass());
        //打印的代理对象是:$EnhancerBySpringCGLIB$$cfffcf3c
        bean.sayHello("这个世界很大");
    }
}
​
结果:
class chencj.cc.aop.Hello$$EnhancerBySpringCGLIB$$cfffcf3c
这里是前置通知,请放心使用
class chencj.cc.aop.Hello$$EnhancerBySpringCGLIB$$cfffcf3c
[Ljava.lang.Object;@4b14c583
这个世界很大
方法执行结束啦

实例2

代理对象是jdkproxy,对接口的实现

接口类,目标类
public interface IHello{
    public void sayHello(String  word);
}
​
实体类实现接口 
public class Hello implements IHello{
​
    public void sayHello(String  word){
        System.out.println(word);
        
    }
}
通知类   就使用      方式1    使用的
public class MyAOP implements MethodBeforeAdvice{
​
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("目标方法调用之前,要开始用");
        
    }
}

application.xml配置

通知类:
    <aop:config>
    
        <aop:pointcut expression="execution(* chencj.cc.aop.Hello.*(..))" id="helloT"/>
        方式1:直接使用确定的通知类接口的实现类
        MethodBeforeAdvice    AfterReturningAdvice等等
        <aop:advisor advice-ref="myAOP" pointcut-ref="helloT"/>
    </aop:config>
​
目标接口的实现类,引入接口到spring容器中
<bean class="chencj.cc.aop.Hello" id="hello"></bean>
通知类
<bean class="chencj.cc.aop.MyAOP" id="myAOP"></bean>

测试

public class Client {
​
    public static void main(String[] args) {
        ApplicationContext applicationContext =  new ClassPathXmlApplicationContext("classpath:application.xml");
        IHello bean =applicationContext.getBean(IHello.class);//这里是从spring容器中拿出接口实例化对象,
        System.out.println(bean.getClass());
        //class com.sun.proxy.$Proxy2
        bean.sayHello("世界你好啊");
    }
}
​
结果是:
class com.sun.proxy.$Proxy2
这里是前置通知,请放心使用
世界你好啊

SpringAOP的注解方式实现

application.xml

<!-- 使用注解自动生成代理对象 -->
  <aop:aspectj-autoproxy/>

通知类上的修改

@Aspect//加入这个切面注解  对应xml中 <aop:aspect> </aop:aspect>
public class MyAOP {
​
    //只有加入@Aspect,才能使得作用在方法上的注解@Before,@After对应xml中<aop:before/> <aop:after>
    //生效,"execution(* chencj.cc.aop.Hello.*(..))"----》对应xml中的<aop:pointcut/>
    @Before("execution(* chencj.cc.aop.Hello.*(..))")
    public void before(JoinPoint joinPoint){
        System.out.println("这里是前置通知,请放心使用");
        System.out.println(joinPoint.getThis().getClass());
        System.out.println(joinPoint.getArgs());
        
    }
    
    
    public void around(){
        
    }
    @After("execution(* chencj.cc.aop.Hello.*(..))")
    public void after(){
        System.out.println("方法执行结束啦");
    }
}

测试

public class Client {
​
    public static void main(String[] args) {
        ApplicationContext applicationContext =  new ClassPathXmlApplicationContext("classpath:application.xml");
        Hello bean = applicationContext.getBean(Hello.class);
        System.out.println(bean.getClass());
        bean.sayHello("这个世界很大");
    }
}
​
结果:
class chencj.cc.aop.Hello$$EnhancerBySpringCGLIB$$fe63c014
这里是前置通知,请放心使用
class chencj.cc.aop.Hello$$EnhancerBySpringCGLIB$$fe63c014
[Ljava.lang.Object;@49b0b76
这个世界很大
方法执行结束啦
​
​
​

总结:注解方式的aop,比xml书写起来要简单,xml看着比较一目了然

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值