• spring之初识Ioc&Aop


    Spring框架的作用

       spring是一个轻量级的企业级框架,提供了ioc容器、Aop实现、dao/orm支持、web集成等功能,目标是使现有的java EE技术更易用,并促进良好的编程习惯。

       Spring框架主要用于与其他技术(struts,hibernate等)进行整合,可将应用程序中的Bean组件实现低耦合关联.最终可以提高系统扩展和维护性.

       将来我们利用Spring框架管理系统的各个组件(Action,Service,DAO).采用Spring的IOC和AOP机制实现各组件的关联.从而实现了低耦合调用.增强了系统可维护性和扩展性.

    Spring基础jar包

      

    Spring ioc 控制反转(Inversion of Control)

      控制反转也被称为依赖注入,是面向对象编程中的一种设计理念,用来减低代码之间的耦合度。

      IoC最大的好处是什么?因为把对象生成放在了XML里定义,所以当我们需要换一个实现子类将会变成很简单(一般这样的对象都是实现于某种接口的),只要修改XML就可以了,这样我们甚至可以实现对象的热插拔(有点像USB接口和SCSI硬盘了)。

    例:

    public class HelloSpring {
        private String who = null;
    
        public void print() {
            System.out.println("hello" + this.getWho());
        }
    
        public String getWho() {
            return who;
        }
    
        public void setWho(String who) {
            this.who = who;
        }
    
    }

    applicationContext.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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!-- services -->
        <!-- 通过bean元素声明需要Spring创建的实例,该实例的类型通过class属性指定,并通过id属性为该实例指定一个唯一名称,以便在程序中使用 -->
        <bean id="helloSpring" class="cn.cnsdhzzl.biz.HelloSpring">
        <!-- 此处name属性的值对应类中属性的setWho,并为value属性赋值‘Spring’ -->
            <property name="who" value="Spring">
            </property>
        </bean>
    
        <!-- more bean definitions for services go here -->
    
    </beans>

    测试类:

        @Test
        public void fristSpring() {
            // 从classpath路径中读取Spring配置文件,实例化Spring的上下文
            ApplicationContext ac = new ClassPathXmlApplicationContext(
                    "applicationContext.xml");
            // 通过上下文的getBean方法,根据xml文件中的id属性值过去bean的实例
            HelloSpring hs = (HelloSpring) ac.getBean("helloSpring");
    
            // 实例调用方法
            hs.print();
    
        }

    注:

    ApplicationContext:是一个接口,负责读取Spring配置文件,管理对象的加载、生成,维护Bean对象与Bean对象质检的依赖关系,负责Bean的生命周期等。
    ClassPathXmlApplicationContext:是ApplicationContext接口的实现类,用于从classPath路径中读取Spring配置文件(FileSystemXMLApplicationContext也可以用于加载Spring配置文件)。
    相对于控制反转,依赖注入的说法也许更容易理解一些,即由容器(如Spring)负责吧组件所依赖的具体对象注入(赋值)给组件,从而避免组件之间以硬编码的方式组织在一起。

     spring Aop(Aspect Oriented Programming)

      在业务系统中,总有一些散落、渗透到系统各处且不得不处理的事情,这些穿插在既定业务中的操作就是所谓的“横切逻辑”,也陈伟‘切面’

      面向切面编程,简单的说就是在不改变源程序的基础上为代码段增加新的功能,对代码段进行增强处理。

      Aop一般适用于具有横切逻辑的场合,如切入日志、访问控制、事务管理、性能检测。

      Aopjar包

      

    例:

    定义一个dao和实现

    public interface UserEntityDao {
        public void save(UserEntity user);
    }

    定义一个biz和实现

    public class UserEntityBizImpl implements UserEntityBiz {
        private UserEntityDao dao;
    
        @Override
        public void save(UserEntity user) {
             dao.save(user);
        }
    
        public UserEntityDao getDao() {
            return dao;
        }
    
        public void setDao(UserEntityDao dao) {
            this.dao = dao;
        }
        
    
    }

    创建前置增强类

    //通过methodBeforeAdvice实现前置增强
    public class LoggerBefore implements MethodBeforeAdvice {
    
        private static final Logger logger = Logger.getLogger(LoggerBefore.class);
    
        @Override
        public void before(Method method, Object[] arguments, Object target)
                throws Throwable {
            logger.info("调用" + target + "的" + method.getName() + "方法。" + "方法入参"
                    + Arrays.toString(arguments));
        }
    
    }

    创建后置增强类

    //通过afterreturningadvice实现后置增强
    public class LoggerAfterReturning implements AfterReturningAdvice {
        private static final Logger logger = Logger
                .getLogger(LoggerAfterReturning.class);
    
        @Override
        public void afterReturning(Object returnValue, Method method,
                Object[] arguments, Object target) throws Throwable {
            logger.info("调用" + target + "的" + method.getName() + "方法" + "方法返回值:"
                    + returnValue);
        }
    
    }

    配置applicationContext.xml

    <!-- 声明要创建的实体类 -->
        <bean id="daoImpl" class="cn.cnsdhzzl.dao.impl.UserEntityDaoImpl"></bean>
    
        <bean id="biz" class="cn.cnsdhzzl.biz.impl.UserEntityBizImpl">
            <property name="dao" ref="daoImpl"></property>
        </bean>
    
    
        <bean id="loggerBefore" class="cn.cnsdhzzl.aop.LoggerBefore"></bean>
        <bean id="loggerAfterReturning" class="cn.cnsdhzzl.aop.LoggerAfterReturning"></bean>
    
        <!-- 定义切入点 -->
        <aop:config>
            <aop:pointcut id="pointcut"
                expression="execution(public void save(cn.cnsdhzzl.entity.UserEntity))" />
            <!-- 插入增强处理(织入) -->
            <aop:advisor advice-ref="loggerBefore" pointcut-ref="pointcut" />
            <aop:advisor advice-ref="loggerAfterReturning"
                pointcut-ref="pointcut" />
        </aop:config>

    注:

    exection是切入点指示符,他的括号中是一个切入点表达式,可以配置要切入的方法,切入点表达式支持模糊匹配

     

    • 任意公共方法的执行:
      execution(public * *(..))
    • 任何一个名字以“set”开始的方法的执行:
      execution(* set*(..))
    • AccountService接口定义的任意方法的执行:
      execution(* com.xyz.service.AccountService.*(..))
    • 在service包中定义的任意方法的执行:
      execution(* com.xyz.service.*.*(..))
    • 在service包或其子包中定义的任意方法的执行:
      execution(* com.xyz.service..*.*(..))
    • 在service包中的任意连接点(在Spring AOP中只是方法执行):
      within(com.xyz.service.*)
    • 在service包或其子包中的任意连接点(在Spring AOP中只是方法执行):
      within(com.xyz.service..*)
    • 实现了AccountService接口的代理对象的任意连接点 (在Spring AOP中只是方法执行):
      this(com.xyz.service.AccountService)
      'this'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得代理对象在通知体内可用。
       
    • 实现AccountService接口的目标对象的任意连接点 (在Spring AOP中只是方法执行):
      target(com.xyz.service.AccountService)
      'target'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得目标对象在通知体内可用。
       
    • 任何一个只接受一个参数,并且运行时所传入的参数是Serializable 接口的连接点(在Spring AOP中只是方法执行)
      args(java.io.Serializable)
      'args'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得方法参数在通知体内可用。
      请注意在例子中给出的切入点不同于 execution(* *(java.io.Serializable)): args版本只有在动态运行时候传入参数是Serializable时才匹配,而execution版本在方法签名中声明只有一个 Serializable类型的参数时候匹配。
    • 目标对象中有一个 @Transactional 注解的任意连接点 (在Spring AOP中只是方法执行)
      @target(org.springframework.transaction.annotation.Transactional)
      '@target'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得注解对象在通知体内可用。
       
    • 任何一个目标对象声明的类型有一个 @Transactional 注解的连接点 (在Spring AOP中只是方法执行):
      @within(org.springframework.transaction.annotation.Transactional)
      '@within'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得注解对象在通知体内可用。
       
    • 任何一个执行的方法有一个 @Transactional 注解的连接点 (在Spring AOP中只是方法执行)
      @annotation(org.springframework.transaction.annotation.Transactional)
      '@annotation'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得注解对象在通知体内可用。
       
    • 任何一个只接受一个参数,并且运行时所传入的参数类型具有@Classified 注解的连接点(在Spring AOP中只是方法执行)
      @args(com.xyz.security.Classified)
      '@args'在绑定表单中更加常用:- 请参见后面的通知一节中了解如何使得注解对象在通知体内可用。
       
    • 任何一个在名为'tradeService'的Spring bean之上的连接点 (在Spring AOP中只是方法执行):
      bean(tradeService)
    • 任何一个在名字匹配通配符表达式'*Service'的Spring bean之上的连接点 (在Spring AOP中只是方法执行):
      bean(*Service)
  • 相关阅读:
    父子传值
    第三次作业
    第二次作业
    最后一次作业--总结报告
    Vue项目axios请求设置responseType无效
    滚动条样式修改
    超出部分显示省略号,鼠标悬浮显示详细文本,el-tooltip
    大屏rem
    js比较时间大小
    kindeditor编辑器上传图片跨域
  • 原文地址:https://www.cnblogs.com/cnsdhzzl/p/5908779.html
Copyright © 2020-2023  润新知