大数据正式29 清疚 2022-06-03 06:13 134阅读 0赞 # 大数据正式29 # ### Spring中的AOP ### * 代理模式 * 特点 1. 具备和被代理者相同的方法 2. 代理者不仅要做目标对象的方法,而且还要做额外的一些方法 * 操作 1. 事务 2. 权限控制 3. 统计每个方法的执行时间 * 分类 * 静态代理 * 之前 * ![1Hdof9u.png][] * 代理 * ![LueZv9m.png][] * 动态代理 * 之前 * ![1Hdof9u.png][] * 代理 * ![VSDmsok.png][] * 代理模式的来源 * 之前的service层耦合了事务的控制等操作--耦合度太高 * 解决的小案例(静态代理) * pojo * BigBoss # # package com.peng.pojo; import org.springframework.stereotype.Component; @Component(value = "bigboss") public class BigBoss implements SellInterface { @Override public void sellAction() { System.out.println("boss sell home!"); } } * LinkHome # # package com.peng.pojo; import org.springframework.stereotype.Component; @Component(value = "bigboss") public class BigBoss implements SellInterface { @Override public void sellAction() { System.out.println("boss sell home!"); } } * Manager # # package com.peng.pojo; import org.springframework.stereotype.Component; @Component(value = "bigboss") public class BigBoss implements SellInterface { @Override public void sellAction() { System.out.println("boss sell home!"); } } * SellInterface # # package com.peng.pojo; import org.springframework.stereotype.Component; @Component(value = "bigboss") public class BigBoss implements SellInterface { @Override public void sellAction() { System.out.println("boss sell home!"); } } * test * Test # # package com.peng.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.peng.pojo.LinkHome; public class Test { @org.junit.Test public void Test_Agent() { ApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml"); LinkHome linkhome = (LinkHome) context.getBean("linkhome"); linkhome.sellAction(); } } * 配置文件 * applicationContext.xml # # <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <!-- 开启包扫描 --> <context:component-scan base-package="com.peng"></context:component-scan> <!-- 开启注解开关 --> <context:annotation-config></context:annotation-config> </beans> ### MVC的静态代理 ### * 项目结构 * ![suqxzF9.png][] * 代码示例 * dao * PersonDao # # package com.peng.dao; import com.peng.pojo.Person; public interface PersonDao { void savePerson(Person p); } * PersonDaoImpl # # package com.peng.dao; import com.peng.pojo.Person; public interface PersonDao { void savePerson(Person p); } * service * PersonService # # package com.peng.dao; import com.peng.pojo.Person; public interface PersonDao { void savePerson(Person p); } * PersonServiceImpl # # package com.peng.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import com.peng.dao.PersonDao; import com.peng.pojo.Person; @Service(value = "serviceImpl") public class PersonServiceImpl implements PersonService { @Autowired @Qualifier(value = "personDao") private PersonDao dao; @Override public void savePerson(Person p) { if (null != dao) { dao.savePerson(p); } } } * web * PersonServlet # # package com.peng.web; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import com.peng.pojo.Person; import com.peng.service.PersonService; @Controller(value = "personServlet") public class PersonServlet { @Autowired @Qualifier(value = "personserviceproxy") private PersonService proxy; public void doSomething(Person p) { proxy.savePerson(p); } } * proxy * PersonServiceProxy # # package com.peng.web; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import com.peng.pojo.Person; import com.peng.service.PersonService; @Controller(value = "personServlet") public class PersonServlet { @Autowired @Qualifier(value = "personserviceproxy") private PersonService proxy; public void doSomething(Person p) { proxy.savePerson(p); } } * manager * Manager # # package com.peng.web; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import com.peng.pojo.Person; import com.peng.service.PersonService; @Controller(value = "personServlet") public class PersonServlet { @Autowired @Qualifier(value = "personserviceproxy") private PersonService proxy; public void doSomething(Person p) { proxy.savePerson(p); } } * test * Test # # package com.peng.test; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.peng.pojo.Person; import com.peng.web.PersonServlet; public class Test { @org.junit.Test public void trest1() { ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext( "applicationContext.xml"); System.out.println("=================懒加载在此之后================="); Person person = (Person) ac.getBean("person"); PersonServlet servlet = (PersonServlet) ac.getBean("personServlet"); servlet.doSomething(person); ac.close(); } } * pojo * Person # # package com.peng.pojo; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Scope(value = "singleton") @Lazy(value = true) @Component(value = "person") public class Person { @Value(value = "张三") private String name; @Value(value = "12") private Integer age; private Person() { super(); System.out.println("============构造函数==========="); } private Person(String name, Integer age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "名称:" + name + ",年龄:" + age; } @PostConstruct public void init() { System.out.println("=====Person=====init=========="); } @PreDestroy public void destory() { System.out.println("=====Person=====destory=========="); } } * 配置文件 * applicationContext.xml # # <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <!-- 开启包扫描 --> <context:component-scan base-package="com.peng"></context:component-scan> <!-- 开启注解开关 --> <context:annotation-config></context:annotation-config> </beans> * 执行结果 # # 十二月 20, 2017 10:26:03 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@dfe491: startup date [Wed Dec 20 10:26:03 CST 2017]; root of context hierarchy 十二月 20, 2017 10:26:03 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [applicationContext.xml] 十二月 20, 2017 10:26:04 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@cb855e: defining beans [personDao,manager,person,personserviceproxy,serviceImpl,personServlet,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy =================懒加载在此之后================= ============构造函数=========== =====Person=====init========== start................ 保存了~~名称:张三,年龄:12 commit................ 十二月 20, 2017 10:26:05 上午 org.springframework.context.support.AbstractApplicationContext doClose INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@dfe491: startup date [Wed Dec 20 10:26:03 CST 2017]; root of context hierarchy 十二月 20, 2017 10:26:05 上午 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@cb855e: defining beans [personDao,manager,person,personserviceproxy,serviceImpl,personServlet,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy =====Person=====destory========== ### 静态代理的优缺点 ### * 优点 * 解耦 * 缺点 * 一个代理只服务一个被代理者,重复代码太多 ### 动态代理 ### * JDK的动态代理方式 * 优点: * 继承静态代理的优点 * 一个代理类可以为多个目标类服务 * 实现了代码的分离 * 实现了代码的复用,before和after可以根据不同场景来指定不同的操作 * 缺点: * 只能处理事务,不具有通用性 * 必须实现接口,否则创建不了对象 * 目标类的每个方法都经过判断,降低性能 * 关键代码 * DynamicProxy # # package com.peng.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public abstract class DynamicProxy { public Object getProxy(final Object obj) { Object proxy_ob = Proxy.newProxyInstance(obj.getClass() .getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /* 被代理的对象的方法任意执行的这里都执行 */ // 执行before方法 before(); // 执行目标方法 Object result = method.invoke(obj, args); // 执行after方法 after(); return result; } }); return proxy_ob; } protected abstract void before(); protected abstract void after(); } * PersonDynamicProxy # # package com.peng.proxy; import org.springframework.stereotype.Component; @Component(value = "persondynamicproxy") public class PersonDynamicProxy extends DynamicProxy { @Override protected void before() { System.out.println("person-------------------start"); } @Override protected void after() { System.out.println("person-------------------after"); } } * Test # # package com.peng.test; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.peng.pojo.Person; import com.peng.web.PersonServlet; public class Test { @org.junit.Test public void trest1() { ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext( "applicationContext.xml"); System.out.println("=================懒加载在此之后================="); Person person = (Person) ac.getBean("person"); PersonServlet servlet = (PersonServlet) ac.getBean("personServlet"); servlet.doSomething(person); ac.close(); } } * 。。。 * 执行结果 # # 十二月 20, 2017 11:25:19 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@dfe491: startup date [Wed Dec 20 11:25:19 CST 2017]; root of context hierarchy 十二月 20, 2017 11:25:19 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [applicationContext.xml] 十二月 20, 2017 11:25:19 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@cb855e: defining beans [personDao,manager,person,persondynamicproxy,serviceImpl,personServlet,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy =================懒加载在此之后================= ============构造函数=========== =====Person=====init========== person-------------------start 保存了~~名称:张三,年龄:12 person-------------------after 十二月 20, 2017 11:25:19 上午 org.springframework.context.support.AbstractApplicationContext doClose INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@dfe491: startup date [Wed Dec 20 11:25:19 CST 2017]; root of context hierarchy 十二月 20, 2017 11:25:19 上午 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@cb855e: defining beans [personDao,manager,person,persondynamicproxy,serviceImpl,personServlet,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy =====Person=====destory========== * Cglib方式的动态代理 * cglib是Spring中的动态代理 * 优点: 1. 继承jdk动态代理的优点 2. 不需要类必须有实现的接口 * 缺点: * 过滤过于麻烦 * 例子 # # package com.peng.proxy; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public abstract class DynamicProxy { public Object getProxy(final Object obj) { // 创建一个增强器 Enhancer enhancer = new Enhancer(); // 设置父接口 enhancer.setInterfaces(obj.getClass().getInterfaces()); // 设置父类 enhancer.setSuperclass(obj.getClass()); // 设置接口 enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("asdfghj"); Object result = arg1.invoke(obj, arg2); System.out.println("asdfghj"); return result; } }); return enhancer.create(); } protected abstract void before(); protected abstract void after(); } ### Spring的AOP ### * 优点 1. 继承所有优点+过滤简单 * 原理 * 通过两种动态代理来实现,进行了封装 * AOP,是一种编程思想,可以实现把某些具体的功能放到一个切面(类),然后在改动原来的代码的基础上同时将切面插入到工程当中,实现最低限制的解耦 * SpringAOP的概念 * 切面(Aspect):就是一个类:如事务的控制,权限控制类,日志输出切面类 * 连接点(JoinPoint):具体的方法(之前,之后进行操作,所以这个目标类中的方法就是连接点) * 通知(Advice):切面中的方法 1. 前置通知 2. 后置通知 3. 最终通知 4. 环绕通知 5. 异常通知 * 切入点(PointCut):匹配连接点的断言,方法过滤的规则 * 步骤 1. 导jar包,约束文件 2. 事务切面类 3. 配置文件 1. 切入点:切入点标点时(一定在切面的上面)expression id 2. 切面:ref 1. 方法(前置,后置...)point-ref,method * 例子 * 流程 * [![68fgeMf.png][]][68fgeMf.png] * 切面类 # # package com.peng.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import com.peng.manager.Manager; /** * 切面 * * @author Administrator * */ @Component(value = "txaspect") public class TxAspect { @Autowired @Qualifier(value = "manager") Manager manager; // 此方法当代理对象执行方法的时候去执行 public Object around(ProceedingJoinPoint joinPoint) throws Throwable { manager.start();// 开始事务 // 执行目标方法 Object result = joinPoint.proceed(); manager.commit();// 提交事务 return result; } } * 配置文件 # # <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"> <!-- 开启包扫描 --> <context:component-scan base-package="com.peng"></context:component-scan> <!-- 开启注解开关 --> <context:annotation-config></context:annotation-config> <aop:config> <!-- 切入点(规则:其实就是个路径) --> <aop:pointcut expression="within(com.peng.service.*)" id="pc" /> <!-- 配置切面 --> <aop:aspect ref="txaspect"> <!-- 方法 通知 --> <aop:around method="around" pointcut-ref="pc" /> </aop:aspect> </aop:config> </beans> ### 补充 ### * ![MJhYab1.jpg][] [1Hdof9u.png]: https://i.imgur.com/1Hdof9u.png [LueZv9m.png]: https://i.imgur.com/LueZv9m.png [VSDmsok.png]: https://i.imgur.com/VSDmsok.png [suqxzF9.png]: https://i.imgur.com/suqxzF9.png [68fgeMf.png]: https://i.imgur.com/68fgeMf.png [MJhYab1.jpg]: https://i.imgur.com/MJhYab1.jpg
相关 大数据正式5 大数据正式5 常见的shell命令 管道命令 管道符| 将两个命令隔开,左边命令的输出就会作为管道右边命令的输入 连续使 旧城等待,/ 2022年06月06日 10:29/ 0 赞/ 215 阅读
相关 大数据正式2 大数据正式2 用户身份与用户组记录的文件 在Linux系统当中,默认情况下所有的系统上的账号信息都记录在/etc/passwd这个文件内(包括root用户), 快来打我*/ 2022年06月06日 08:38/ 0 赞/ 141 阅读
相关 大数据正式10 大数据正式10 jQuery 定义:jQuery是一个“写的更少”,但“做的更多”的轻量级JavaScript函数库 优势 1. 可 ゞ 浴缸里的玫瑰/ 2022年06月05日 06:24/ 0 赞/ 222 阅读
相关 大数据正式32 大数据正式32 Spring中的JDBC jar包准备 ![zW1gEQQ.png][] bean+properties普通配置 悠悠/ 2022年06月03日 08:44/ 0 赞/ 146 阅读
相关 大数据正式27 大数据正式27 Spring 先来张图简单看一下 ![oQySJMC.png][] spring框架的特点 1 悠悠/ 2022年06月03日 04:38/ 0 赞/ 127 阅读
相关 大数据正式37 大数据正式37 Maven 传统项目存在的弊端 1. 导入jar包得经验丰富 2. 传统项目打包方式不通用,不能很好的支持聚合项 左手的ㄟ右手/ 2022年06月02日 01:46/ 0 赞/ 138 阅读
相关 大数据正式36 大数据正式36 MyBatis的接口形式 注意两点 1. 接口名---namespace值对应 2. 方法名---id一致 淩亂°似流年/ 2022年06月02日 01:12/ 0 赞/ 244 阅读
相关 大数据正式34 大数据正式34 Spring+SpringMVC 小例子 效果图 ![hsIEQmd.png][] 功能说明 川长思鸟来/ 2022年06月02日 00:16/ 0 赞/ 256 阅读
还没有评论,来说两句吧...