大数据正式29

大数据正式29

Spring中的AOP

  • 代理模式
    • 特点
      1. 具备和被代理者相同的方法
      2. 代理者不仅要做目标对象的方法,而且还要做额外的一些方法
    • 操作
      1. 事务
      2. 权限控制
      3. 统计每个方法的执行时间
    • 分类
      • 静态代理
        • 之前
        • 代理
      • 动态代理
        • 之前
        • 代理
  • 代理模式的来源

    • 之前的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

          
          
              
              
              
              
          
          

MVC的静态代理

  • 项目结构
  • 代码示例

    • 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

        
        
            
            
            
            
        
        
    • 执行结果

      十二月 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
  • 例子

    • 流程
    • 切面类

      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;
          }
      
      }
      
    • 配置文件

      
      
          
          
          
          
          
              
              
              
              
                  
                  
              
          
      
      

补充

你可能感兴趣的:(达内实训,大数据学习痕迹)