您的位置:首页 > 编程语言 > Java开发

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

2018-01-23 22:46 781 查看
2018年1月23日 21:57:48

静态代理 动态代理 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);
}

}

下面附上本天课第一个项目 静态代理 动态代理 CGLIB  AOP切入点切面 所有类代码

package com.bdqn.entity;

public interface Person {
void say();

}

###############################################################

package com.bdqn.entity;

public class OldPerson implements Person{

@Override
public void say() {
// TODO Auto-generated method stub
System.out.println("小伙子,不错啊,哈哈");
}

}

###############################################################

package com.bdqn.entity;

public class PersonProxy implements Person{

Person person=new OldPerson();

@Override
public void say() {
// TODO Auto-generated method stub
person.say();
}

}

################################################################

package com.bdqn.entity;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

/**

 * 

 * @author Administrator

 *动态代理

 */

public class SysProxy implements InvocationHandler{
//第一步实现接口

//目标对象
private Object object1;

//得到代理对象 测试了就是调用这个方法
public Object getProxy(Object object2){

this.object1=object2;//把传进来的参数也就是具体对象赋值给本类的对象来用

//注意导包
Object object3=Proxy.newProxyInstance(object2.getClass().getClassLoader(), object2.getClass().getInterfaces(), this);
return object3;
}

//动态的调用目标对象得的方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub

Object object4=method.invoke(object1, args);
return object4;
}

}

################################################################################################

package com.bdqn.entity;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor{

//第一步 添加jar包依赖 实现接口

//私有化目标对象
private Object object1;

public CglibProxy() {
super();
}

//有参数构造
public CglibProxy(Object object2) {
super();
this.object1 = object2;
}

//获得代理
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;
}

}

#######################################################################################################3

package com.bdqn.entity;

import java.io.Serializable;

public class User implements Serializable{
private String uName;
private String uPwd;
public User() {
super();
}
public User(String uName, String uPwd) {
super();
this.uName = uName;
this.uPwd = uPwd;
}
@Override
public String toString() {
return "User [uName=" + uName + ", uPwd=" + uPwd + "]";
}
public String getuName() {
return uName;
}
public void setuName(String uName) {
this.uName = uName;
}
public String getuPwd() {
return uPwd;
}
public void setuPwd(String uPwd) {
this.uPwd = uPwd;
}

}

############################################################################

package com.bdqn.dao;

public interface UserDao {
void shut();
String zhichi(int sum);

}

#############################################################################

package com.bdqn.daoImpl;

import javax.management.RuntimeErrorException;

import com.bdqn.dao.UserDao;

public class UserDaoImpl implements UserDao{

@Override
public void shut(){
// TODO Auto-generated method stub
System.out.println("用户类 shut 了"+"\n"+"切入面");
//throw new RuntimeException();
}

@Override
public String zhichi(int sum) {
// TODO Auto-generated method stub
System.out.println("传进了的int类型sum值是:"+sum);
return "Hello KGC!";
}

}

###########################################################################################

package com.bdqn.service;

public interface UserService {
void shut();
String zhichi(int sum);

}

#########################################################################################3

package com.bdqn.serviceImpl;

import com.bdqn.dao.UserDao;

import com.bdqn.daoImpl.UserDaoImpl;

import com.bdqn.service.UserService;

public class UserServiceImpl implements UserService{
private UserDao userDao;

public UserDao getUserDao() {
return userDao;
}

public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}

@Override
public void shut() {
// TODO Auto-generated method stub
userDao.shut();
}

@Override
public String zhichi(int sum) {
// TODO Auto-generated method stub
return userDao.zhichi(sum);
}

}

############################################################################################

package com.bdqn.test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.bdqn.entity.CglibProxy;

import com.bdqn.entity.ErMian;

import com.bdqn.entity.OldPerson;

import com.bdqn.entity.Person;

import com.bdqn.entity.PersonProxy;

import com.bdqn.entity.SysProxy;

import com.bdqn.service.UserService;

import com.bdqn.serviceImpl.UserServiceImpl;

public class Test {
public static void main(String[] args) {

//静态代理 Person接口声明say方法 OldPerson实现接口说小伙不错 代理也实现Person接口 newOldPerson 实现的方法里调用Oldperson的方法

// PersonProxy personProxy=new PersonProxy();

// personProxy.say();

//动态代理 第一步代理类InvocationHandler接口 声明私有OBJ对象  

// Person person=new OldPerson();//这个动态弊端是只能多态

// SysProxy sysProxy=new SysProxy();

// Person person2=(Person) sysProxy.getProxy(person);

// person2.say();

//CGLIB动态代理 第一步添加jar包实现接口 第二步 私有化属性  第三步 有参数构造 第四步 获得代理方法 第五步动态调用方法的方法

// OldPerson oldPerson=new OldPerson();

// CglibProxy cglibProxy=new CglibProxy(oldPerson);

// OldPerson oldPerson2=(OldPerson) cglibProxy.getProxy();

// oldPerson2.say();

//切入点 切入到哪个类去 切面那个面切进去 通知到哪个切入点
ApplicationContext AC=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService) AC.getBean("userserviceimpl");
userService.shut();
ErMian erMian=(ErMian) AC.getBean("ermian");
erMian.run();
}

}

#######################################################################################################

<?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相关语句 -->
<context:component-scan base-package="com.bdqn.service"></context:component-scan>

<bean id="userdaoimpl" class="com.bdqn.daoImpl.UserDaoImpl"></bean>
<bean id="ermian" class="com.bdqn.entity.ErMian"></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=写的是要插入到哪个类之前 -->
<aop:pointcut
expression="execution(* com.bdqn.serviceImpl.UserServiceImpl.*(..))"
id="qierudian" />
<!-- 切面 ref=写的是要插入的类 -->
<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>

</beans>

<!-- ? -->

#################################################################################################

package com.bdqn.entity;

public class Mian {
public void qian(){
System.out.println("before 是 在某连接点之前执行的通知");
}

public void ret(){
System.out.println("returning 是 在某连接点正常完成之后通知");
}

public void thr(){
System.out.println("throwing 是 在方法抛出异常退出时执行的通知");
}

public void aro(){
System.out.println("around 是 包围一个连接点的通知");
}
public void hou(){
System.out.println("after 是 在某连接点退出时执行的通知");
}

}

################################################################################################

package com.bdqn.entity;

public class ErMian {
public void run(){
System.out.println("跑步"+"\n"+"跑了十圈");
}

}

################################################

下面附上本天课第二个项目 AOP注解 所有类代码

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);
}

}

#################################################################################
<?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>

<bean class="com.bdqn.entity.ZhuJieMianDaiLi"></bean>

<!-- 开启AOP注解支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

<!-- ? -->

##################################################################################################################
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.entity;

import java.io.Serializable;

public class User implements Serializable{
private String uName;
private String uPwd;
public User() {
super();
}
public User(String uName, String uPwd) {
super();
this.uName = uName;
this.uPwd = uPwd;
}
@Override
public String toString() {
return "User [uName=" + uName + ", uPwd=" + uPwd + "]";
}
public String getuName() {
return uName;
}
public void setuName(String uName) {
this.uName = uName;
}
public String getuPwd() {
return uPwd;
}
public void setuPwd(String uPwd) {
this.uPwd = uPwd;
}

}

########################################################################################################
package com.bdqn.dao;

public interface UserDao {
void shut();
String zhichi(int sum);

}

############################################################################################33333
package com.bdqn.daoImpl;

import javax.management.RuntimeErrorException;

import org.springframework.stereotype.Repository;

import com.bdqn.dao.UserDao;

@Repository("userDao")

public class UserDaoImpl implements UserDao{

@Override
public void shut(){
// TODO Auto-generated method stub
System.out.println("用户类 shut 了"+"\n"+"切入面");
//throw new RuntimeException();
}

@Override
public String zhichi(int sum) {
// TODO Auto-generated method stub
System.out.println("传进了的int类型sum值是:"+sum);
return "Hello KGC!";
}

}

#######################################################################################################
package com.bdqn.service;

public interface UserService {
void shut();
String zhichi(int sum);

}

######################################################################################################

package com.bdqn.serviceImpl;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.stereotype.Service;

import com.bdqn.dao.UserDao;

import com.bdqn.daoImpl.UserDaoImpl;

import com.bdqn.service.UserService;

@Service("service")

public class UserServiceImpl implements UserService{
@Autowired
//@Qualifier
private UserDao userDao;

public UserDao getUserDao() {
return userDao;
}

public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}

@Override
public void shut() {
// TODO Auto-generated method stub
userDao.shut();
}

@Override
public String zhichi(int sum) {
// TODO Auto-generated method stub
System.out.println("逻辑层实现了");
return userDao.zhichi(sum);
}

}
################################################################################################################

?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐