• Spring的IOC注解开发与AOP


    一 IOC实现的注解形式

    1SpringAOP的常用注解

       官方建议使用这三个衍生注解,层次清晰,针对每一层
      @Controller web层
      @Service service层
      @Responsitory dao层

    @Autowired 注入对象,按类型注入。我们一般都是按照名称来注入,加一个Qualifier注解,必须让@Autowired和@Qualifier一起来使用,来完成按照名称的属性注入,
    一般属性用value,对象属性用Resource

    代码实现:

    (1)编写UserDao的接口

    package com.itheima.demo1;
    
    public interface UserDao {
        public void save();
    }

    (2)ApplicationContext.xml配置

    (3)编写UserDao的实现类

    package com.itheima.demo1;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Repository;
    //标记数据访问组件,即UserDao
    @Repository("UserDao")
    public class UserDaoImpl implements UserDao {
        @Value("花花")
        private String name;
        @Override
        public void save() {
            System.out.println("UseDao的save方法执行了"+"        姓名是"+name);
        }
    }

    (4)测试类

    public class TestDemo1 {
        /**
         * 使用注解的方式实现
         * demo1使用的是UserDao
         */
        @Test
        public void demo1(){
         ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
            UserDao userDao= (UserDao) applicationContext.getBean("UserDao");
            userDao.save();
        }
        }

    运行成功的结果图:


    2 Bean作用的作用范围的注解(重点):

      @scope
        singleton:单例
        prototype:多例

    3 Bean的声明周期的注解

       初始化的注解:PostCostrucct
       销毁的注解:PerDestroy

    代码片段

     4XML和注解的比较

      XML:适合任何场景               特点:结构清晰,方便维护
      注解:有些地方用不了(这个类不是自己提供的)  特点:开发方便
    XML和注解整合开发(各取所长),XML管理Bean、注解属性注入

    二 AOP的开发

    1 什么是AOP?

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程。AOP是OOP的扩展、延申,解决oop开发遇到的问题。

    利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

    2 AOP采用的是横向抽取机制(代理机制)取代了传统的纵向继承.

    Spring底层的AOP实现原理是动态代理
      jdk的动态代理:只能对实现接口的类实现动态代理
      Cglib动态代理(类似于Javassist第三方的动态代理)

    3  jdk的动态代理部分代码实现

    jdkProxy类

    package com.baidu.demo;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class JdkProxy implements InvocationHandler {
        private UserService userService;
        //把增强的对象传到proxy中
    
       public JdkProxy(UserService userService) {
            this.userService=userService;
        }
    
         public UserService createProxy(){
                UserService Userproxy=(UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), this);//当时这里写错了
              return Userproxy;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //如果是save方法,那么就加强
            if("save".equals(method.getName())){
                System.out.println("权限校验成功了.............");
                return method.invoke(userService,args);
            }
            return method.invoke(userService,args);
        }
    }

    4 Cglib动态代理的部分代码实现

    package com.baidu.demo2;
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class CglibProxy implements MethodInterceptor {
        //把要增强的类传进来
        CustomerDao customerDao=new CustomerDao();
    
        public CglibProxy(CustomerDao customerDao) {
            this.customerDao = customerDao;
        }
        public CustomerDao createProxy(){
            Enhancer enhancer=new Enhancer();
            //设置父类
            enhancer.setSuperclass(customerDao.getClass());
            //设置回调
            enhancer.setCallback(this);
            CustomerDao customerDao = (CustomerDao) enhancer.create();
            return customerDao;
        }
    
        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            //判断方法是否为空
            if("save".equals(method.getName())){
                //增强
                System.out.println("权限校验成功啦.....");
                return methodProxy.invokeSuper(proxy,args);
            }
            return methodProxy.invokeSuper(proxy,args);
        }
    }

    5  Spring AOP的开发(基于Aspect J的XML方式)
      你要想进行AOP的开发,就必须得了解一些相关的术语

        Joinpoint:只要被拦截的点就成为连接点
        Pointcut:切入点,真正被拦截到的点
        Advice:通知、增强 增强的方法称为是通知,在方法执行之前,称为前置通知。日志记录、性能监控称为是后置通知 
        Introduction:引介。类层面的增强
        Target:被增强的对象
        Weaving:织入。通知应用(action)到目标Target的过程
        Proxy:织入之后产生了一个代理对象
        Aspect:切面多个通知和多个切入点的组合

    6 Spring AOP的XML开发

    通知类型(前三个是我们用的比较多的)
    1前置通知            获得切入点的信息
    2后置通知            获得返回值的类型,afterreturning
    3环绕通知(功能最强的一个通知)   proceed
    4异常抛出通知          用于抛出异常的
    5最终通知
    无论有没有异常,最终通知总会执行的

      (1)Aspect类

    package com.baidu.demo3;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    
    /**
     * 这是一个切面类
     */
    public class aspetctJXMl {
        /**
         * 前置通知
         * @param joinPoint
         */
        //增强权限校验,提供增强的方法
        public void checkPri(JoinPoint joinPoint) {
            System.out.println("权限已经校验啦....." + joinPoint);
        }
    
        /**
         * 后置通知
         * @param result
         * @return
         */
        public String log(Object result){
            System.out.println("日志已经记录下来了....."+result);
            return "aa";
        }
    
        /**
         * 环绕通知,功能最强的一个
         * @param proceedingJoinPoint
         * @return
         */
        public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("环绕之前.......");
            Object proceed = proceedingJoinPoint.proceed();
            System.out.println("环绕之后.......");
            return proceed;
        }
    
        /**
         * 异常抛出通知
         */
        public void afterThrowable(Throwable th){
            System.out.println("异常抛出通知执行了....."+th);
        }
        /**
         * 最终通知
         */
        public void Final(){
            System.out.println("最终通知执行了");
        }
    }
    View Code

       (2)在xml中的配置

    <?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->
        <bean id="productDao" class="com.baidu.demo3.ProductDaoImpl"/>
        <!--将切面类交给spring管理-->
        <bean id="aspect" class="com.baidu.demo3.aspetctJXMl"/>
        <!--AOP的配置-->
        <aop:config>
            <aop:pointcut id="product1" expression="execution(* com.baidu.demo3.ProductDaoImpl.save(..))"/>
            <aop:pointcut id="product2" expression="execution(* com.baidu.demo3.ProductDaoImpl.delete(..))"/>
            <aop:pointcut id="product3" expression="execution(* com.baidu.demo3.ProductDaoImpl.update(..))"/>
            <aop:pointcut id="product4" expression="execution(* com.baidu.demo3.ProductDaoImpl.find(..))"/>
    
            <!--配置切面-->
            <aop:aspect ref="aspect">
                <!--前置通知-->
                <aop:before method="checkPri" pointcut-ref="product1"/>
                <!--后置通知-->
                <aop:after-returning method="log" pointcut-ref="product2" returning="result"/>
                <!--环绕通知-->
                <aop:around method="around" pointcut-ref="product3" />
                <!--异常抛出通知-->
                <aop:after-throwing method="afterThrowable" pointcut-ref="product4" throwing="th"/>
                <!--最终通知-->
                <aop:after method="Final" pointcut-ref="product4"/>
            </aop:aspect>
        </aop:config>
    </beans>
    View Code

    7 SPring AOP的注解开发

      (1)Aspect类

    package com.baidu.demo4;
    
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    
    @Component  //组件
    @Aspect     //切面多个通知和多个切入点的组合
    public class aspect {
        //声明一个公共的切入点
        @Pointcut("execution(* com.baidu.demo4.UserService.*(..))") //任意返回值  任意方法   任意参数
        public void myPointCut() {
        }
    
        //增强的方法
        @Before("myPointCut()")
        public void log() {
            System.out.println("日志记录成功啦===============");
        }
    
        @After("myPointCut()")
        public void save() {
            System.out.println("性能检测成功啦=============");
        }
    
        @AfterThrowing("myPointCut()")
        public void b() {
            System.out.println("检测出来了异常===============");
        }
    }

    (2)zhujie.xml

     (3)测试类

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:zhujie.xml")
    public class SpringTest2 {
        @Resource
        private UserService userService;
    
        @Test
        public void demo(){
            userService.find();
            userService.save();
            userService.delete();
        }
    }

    最后,附上一节的Spring框架的快速入门   https://www.cnblogs.com/bao6/p/10388760.html

    英文单词:Component:组件

  • 相关阅读:
    确保消息产生前数据库操作已提交
    信息披露和公司简介总结
    1、清空所有,给当前添加/2、清空上一个,给当前添加。
    不能作为判断条件的:
    excel表格 函数功能
    一种ui app写法
    正则中使用变量及数组去重的方法
    鼠标锁定(消失),进入无限滚动状态
    transform 的旋转 ,3d效果,要添加3d效果的父级加上景深perspective。 3d效果的容器加上 transform-style:preserve-3d。
    rem布局,在用户调整手机字体大小/用户调整浏览器字体大小后,布局错乱问题
  • 原文地址:https://www.cnblogs.com/bao6/p/10403049.html
Copyright © 2020-2023  润新知