Spring入门 静态代理 动态代理 CGLIB AOP切入点切面 AOP注解

静态代理 动态代理 CGLIB AOP切入点切面 AOP注解

第一部分课程内容 静态代理实现步骤

第一步 创建Person接口

代码演示:

package com.bdqn.entity;
public interface Person {
void say();
}
第二步 创建OldPerson类 实现Person接口 重写方法Syso(小伙子不错哦)
package com.bdqn.entity;

public class OldPerson implements Person{
@Override
public void say() {
// TODO Auto-generated method stub
System.out.println("小伙子,不错啊,哈哈");
    }
}
第三步 创建代理类 也实现Person接口
package com.bdqn.entity;
public class PersonProxy implements Person{
//多态 父类引用指向子类
Person person=new OldPerson();
@Override//重写接口的抽象方法
public void say() {
// TODO Auto-generated method stub
person.say();//调用具体对象的方法
    }
}
第四步 测试类的main方法
//静态代理 Person接口声明say方法 OldPerson实现接口说小伙不错 代理也实现Person接口 newOldPerson 实现的方法里调用Oldperson的方法
// PersonProxy personProxy=new PersonProxy();创建代理类
// personProxy.say();调用代理类的方法 代理这个方法里会取找具体对象的方法

第二部分课内容 动态代理

第一步 动态代理类
动态代理类 实现 InvocationHandler 接口

私有化Object类型的object1属性
private Object object1;

公有的有参数返回Object获得代理类方法
把参数object2赋值给私有化的objcet1
声明Object object3=Proxy.newProxyInstance(object2.getClass().getClassLoader(), object2.getClass().getInterfaces(), this);
return object3;

注意Proxy.newProxyInstance();是固定写法

重写接口的抽象方法
Object object4=method.invoke(object1, args);
return object4;

注意object1是已经把参数赋值了object1
args是该方法参数字符串数组的名
第二步 测试类
new 具体对象和代理类 调用代理的获得代理方法把具体对象传进去 返回Object强转成接口 然后调用接口的抽象方法
这个动态代理有个确定就是只能多态不能new实现类传进去返回实现类
//动态代理 第一步代理类InvocationHandler接口 声明私有OBJ对象  
// Person person=new OldPerson();//这个动态弊端是只能多态
// SysProxy sysProxy=new SysProxy();
// Person person2=(Person) sysProxy.getProxy(person);
// person2.say();

第三部分课内容 CGLIB

CGLIB和动态代理相似 但他能解决多态 只能父类引用指向子类 这个CGLIB可以new实现类传进去返回实现类出来
CGLIB和动态代理 不一样的是 实现接口不一样 多了一个有参数构造方法

第一步CglibProxy代理类实现MethodInterceptor接口
私有化属性
//私有化目标对象
private Object object1;
无参数构造方法
有参数构造方法
//有参数构造
public CglibProxy(Object object2) {
super();
this.object1 = object2;
}
Enhancer new出来 set父Class和set回调
//获得代理
public Object getProxy(){
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(object1.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
然后当然是动态调用具体对象的方法
//动态调用目标对象的方法
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
// TODO Auto-generated method stub
Object object3=arg1.invoke(object1, arg2);
return object3;
}
注意arg1是当前方法参数Method 的名,object1是有参数构造方法已经把参数赋值了object1,arg2是当前方法参数Object数组的名


测试类
//CGLIB动态代理 第一步添加jar包实现接口 第二步 私有化属性  第三步 有参数构造 第四步 获得代理方法 第五步动态调用方法的方法
// OldPerson oldPerson=new OldPerson();
// CglibProxy cglibProxy=new CglibProxy(oldPerson);
// OldPerson oldPerson2=(OldPerson) cglibProxy.getProxy();
// oldPerson2.say();

这样就可以返回实现类了

第四部分课 AOP切入点切面

<bean id="userdaoimpl" class="com.bdqn.daoImpl.UserDaoImpl"></bean>
<bean id="userserviceimpl" class="com.bdqn.serviceImpl.UserServiceImpl">
<property name="userDao" ref="userdaoimpl"></property>
</bean>
<bean id="qianmianlei" class="com.bdqn.entity.Mian"></bean>

<aop:config>
<!-- 切入点 expression=写的是要插入到哪个类之前也就是写具体对象类所在 id是自己取的切点名称 -->
<aop:pointcut
expression="execution(* com.bdqn.serviceImpl.UserServiceImpl.*(..))"
id="qierudian" />
<!-- 切面 ref=写的是要插入的类 也就是代理类 首先上面要右bean-->
<aop:aspect ref="qianmianlei">
<!-- method=写的是要插入的代理类要插入的方法名不要括号 pointcut-ref=写的是切入点名称 -->
<aop:before method="qian" pointcut-ref="qierudian" />
<!--<aop:after-returning method="ret" pointcut-ref="qierudian"/> -->
<!--<aop:after-throwing method="thr" pointcut-ref="qierudian"/> -->
<!--<aop:around method="aro" pointcut-ref="qierudian"/> -->
<aop:after method="hou" pointcut-ref="qierudian" />
</aop:aspect>
</aop:config>

切面代理类里写各个方法
测试类
//切入点 切入到哪个类去 切面那个面切进去 通知到哪个切入点
ApplicationContext AC=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService) AC.getBean("userserviceimpl");
userService.shut();

第五部分课内容 AOP注解

代码演示:

首先是配置文件必须在头部加入contxt和AOP那些 还有jar包添加依赖
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
">

<!-- 首先要在头部上面添加 那几句contxt相关语句扫描包 然后开启AOP注解支持-->
<context:component-scan base-package="com.bdqn.entity,com.bdqn.dao,com.bdqn.daoImpl,com.bdqn.service,com.bdqn.serviceImpl,com.bdqn.test"></context:component-scan>

<!-- 没有id的代理类bean -->>
<bean class="com.bdqn.entity.ZhuJieMianDaiLi"></bean>

<!-- 开启AOP注解支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
UserDaoImpl类上@Repository("userDao")
UserServiceImpl类上@Service("service")下@Autowired

ZhuJieMianDaiLi类上切面@Aspect下切点方法上@Pointcut(value="execution(* com.bdqn.serviceImpl.UserServiceImpl.*(..))")要插入到哪个类具体对象类
要执行的之前方法上@Before(value="qie()")
要执行的之后方法上@After(value="qie()")

具体代理类代码
package com.bdqn.entity;


import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;


@Aspect
public class ZhuJieMianDaiLi {
@Pointcut(value="execution(* com.bdqn.serviceImpl.UserServiceImpl.*(..))")
public void qie(){}

@Before(value="qie()")
public void tongzhiqian(){
System.out.println("代理注解通知前的");
}
@After(value="qie()")
public void tongzhihou(){
System.out.println("代理注解通知后的");
    }
}
测试类
package com.bdqn.test;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;




import com.bdqn.service.UserService;
import com.bdqn.serviceImpl.UserServiceImpl;


public class Test {
public static void main(String[] args) {
//代理注解 首先要在头部上面添加 那几句contxt相关语句扫描包 然后开启AOP注解支持
//第二步配置文件里代理类bean calss=全包名.类名 可以不写id
//第三步 UserDaoImpl类 类名上@Repository("userDao")
//第四步 UserService类 类名上@Service("service") 类名下@Autowired
//第五步 xml文件开启AOP注解支持<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
//第六步 测试类 只能多态父类引用指向子类
ApplicationContext ACC=new ClassPathXmlApplicationContext("applicationContextZhuJie.xml");
UserService userService=(UserService) ACC.getBean("service");
String str=userService.zhichi(88);
System.out.println(str);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值