首页 > 其他分享 >spring入门aop和ioc

spring入门aop和ioc

时间:2024-06-05 14:25:07浏览次数:16  
标签:配置文件 spring void 通知 aop ioc public

目录

spring分层架构

  1. 表现层

    springmvc

  2. 服务层(业务层)

    spring ioc

  3. 持久层

    mybatis

    mybatis plus

    hibernite

互联网项目,多ssm结构

spring核心

  1. ioc(控制反转)

    ioc将对象的创建权利交给spring框架,底层实际上是使用反射实现的。降低程序的耦合度

    1)接下来是代码示例:

    1. 创建一个空的maven项目

    2. 引入一些基本依赖

    <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.0.2.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.12</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
    
        </dependencies>
    
    1. 准备实体类

      // 创建一个接口
      public interface UserService {
          public void hello();
      }
      // 创建一个实体类
      public class UserServiceImpl implements UserService {
          @Override
          public void hello() {
              System.out.println("Hello, world!");
          }
      }
      
      
    2. 准备配置文件

      <?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">
          <bean id="us" class="实体类的路径"></bean>
      </beans>
      
    3. 在test中测试

      // 常规方法
          @Test
          public void testUser() {
              // TODO: write test cases for UserService
              UserService userService = new UserServiceImpl();
              userService.hello();
          }
      // 基于ioc容器管理的方法,ioc是一个map key是对象的标识,value是ioc创建的对象
          @Test
          public void run1() {
              // 创建spring ioc工厂
              ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
              // 获取bean
              UserService userService = (UserService) ac.getBean("us");
              userService.hello();
          }
      

    上面就是一个关于ioc容器的示例

    2)ioc容器的使用过程

    ApplicationContext接口,这个工厂接口,使用这个接口就可以获得相应的Bean对象,该对象下有两个实现类

    1. ClassPathXmlApplicationContext:加载类路径下的spring配置文件(常用)
    2. FileSystemXmlApplicationContext:加载本地磁盘下的spring配置文件(让项目和配置文件分离管理,不常用)

    3)ioc中的bean管理

    1. id属性:bean的别名,取名要求:必须要字母开头,可以使用数字,连字符,下划线,字母,不能出现特殊字符
    2. class属性:bean对象的全路径
    3. scope属性: bean对象的作用范围
      1. singleton:单例(默认)生命周期和配置文件一样
      2. prototype:多例,不是加载配置文件时创建,而是在获取实例对象时创建
      3. request: 多例,不常用,应用于web项目中,每个请求都会创建一个新的实例对象
      4. session:多例,不常用,应用于web项目中,向一个http session中共享一个实例
    4. init-method:bean对象创建时可以配置一个指定的方法自动调用
    5. destory-method:bean对象销毁时可以配置一个指定的方并自动调用

    4)实例化bean的三种方式

    1. 默认是无参的构造方法

          <bean id="us" class="实体类的路径"></bean>
      
    2. 静态工厂实例化方法(好处是可以自己编写业务逻辑)

      准备一个静态工厂类

      public class StaticFactory {
          public static UserService createUser() {
              // 编写业务逻辑
              // ......
              return new UserServiceImpl();
          }
      }
      

      在xml配置文件中使用

          <bean id="us1" class="com.qc.util.StaticFactory" factory-method="createUser"></bean>
      
    3. 实例化工厂实例化方式

      准备一个可以实例化的类

      public class DFactory {
          public  UserService createUser() {
              // 编写业务逻辑
              return new UserServiceImpl();
          }
      }
      

      在xml配置文件中使用

          <bean id="factory" class="com.qc.util.DFactory"></bean>
          <bean id="us2" factory-bean="factory" factory-method="createUser"></bean>
      
  2. aop(面向切面开发)

    定义

    是一种编辑的范式,是OOP的延续,也是Spring框架中函数编程的一种衍生范式,利用AOP可以对业务的各个部分进行隔离,从而似的业务逻辑各部分之间的耦合度降低,提高了程序的重用性,同时提高了开发的效率,AOP采用横向抽取机制,取代了传统纵向继承体系。

    优势

    1. 运行期间,不修改源代码的情况下,对已有的方法进行增强,减少重复代码
    2. 提高开发效率
    3. 方便维护

    AOP底层原理

    1. 如果使用接口,则使用JDK动态代理技术,如果没有使用接口,使用的是继承则是cglib代理

    AOP相关的术语

    1. Joinpoint(连接点)所谓连接点是指那些被连接到的点,在spring中,这些带点指的是方法,因为spring只支持方法类型的节点
    2. Pointcut(切入点)所谓切入点是我们要对哪些Joinpoint进行拦截的定义
    3. Advice(通知\通知)所谓通知就是指,拦截到Joinpoint之后所要做的情况就就是通知,通知分为,前置通知,后置通知,异常通知,最终通知,环绕通知(切面类中要完成的功能)
    4. Target(目标对象)代理的目标对象
    5. Weaving(织入)是指把增强应用到目标对象来创建新的代理对象的过程
    6. Proxy(代理)一个类被AOP织入增强后,就产生一个结果代理类
    7. Aspect(切面)是切入点+通知的结合,是自己编写和配置

    AOP入门

    1. 导入坐标依赖

      <dependency>
                  <groupId>aopalliance</groupId>
                  <artifactId>aopalliance</artifactId>
                  <version>1.0</version>
              </dependency>
              <!--Spring Aspects-->
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-aspects</artifactId>
                  <version>5.0.2.RELEASE</version>
              </dependency>
              <!--aspectj-->
              <dependency>
                  <groupId>org.aspectj</groupId>
                  <artifactId>aspectjweaver</artifactId>
                  <version>1.8.3</version>
              </dependency>
      
      <?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:context="http://www.springframework.org/schema/context"
             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/context
      http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop.xsd">
      </beans>
      
    2. 编写spirng配置文件中AOP的配置部分

          <!--    bean管理-->
          <bean id="us" class="com.qc.service.impl.UserServiceImpl"/>
          <bean id="myAspect" class="com.qc.util.MyAspect"/>
      
          <!--    配置aop-->
          <aop:config>
              <!--        配置切面-->
              <aop:aspect ref="myAspect">
                  <!--            前缀通知-->
                  <aop:before method="log1" pointcut="execution(public void com.qc.service.impl.UserServiceImpl.save())"/>
                  <!--            后置通知-->
                  <aop:after-returning method="log2"
                                       pointcut="execution(public void com.qc.service.impl.UserServiceImpl.save())"/>
                  <!--            异常通知-->
                  <aop:after-throwing method="log3"
                                      pointcut="execution(public void com.qc.service.impl.UserServiceImpl.save())"/>
                  <!--            最终通知-->
                  <aop:after method="log4"
                             pointcut="execution(public void com.qc.service.impl.UserServiceImpl.save())"/>
      
                  <!--            环绕通知-->
                  <aop:around method="aroundLog"
                              pointcut="execution(public void com.qc.service.impl.UserServiceImpl.save())"/>
              </aop:aspect>
          </aop:config>
      
      import org.aspectj.lang.ProceedingJoinPoint;
      
      public class MyAspect {
          // 自定义切面类 = 切入点+通知
          //通知
          public void log1() {
              System.out.println("前置增强的");
          }
      
          public void log2() {
              System.out.println("后置增强的");
          }
      
          public void log3() {
              System.out.println("异常增强的");
          }
      
          public void log4() {
              System.out.println("最终增强的");
          }
      
      
          public void aroundLog(ProceedingJoinPoint point) {
              try {
                  log1();
                  point.proceed(); // 目标方法调用
                  log2();
              } catch (Throwable e) {
                  e.printStackTrace();
                  log3();
              } finally {
                  log4();
              }
          }
      }
      

      注意环绕通知使用的接口

    通知类型

    1. 前置通知:目标方法执行前进行增强
    2. 后置通知:目标方法执行后进行增强
    3. 异常通知:目标方法出现异常后进行增强
    4. 最终通知:目标方法无论是否异常都进行增强
    5. 环绕通知:目标方法执行前后,都进行增强,不过需要自己书写

    切入点表达式

    • execution([修饰符] 返回值 包名.类名.方法名(参数))
    • 修饰符可以省略不写
    • 返回值类型不能省略,根据方法来编写返回值,可以用星号来代替
    • 包名类型方法名是不能省略的,但是可以用星号来代替,也可以部分代替
    • 参数如果是一个可以用星号来代替,如果是多个可以使用两个点

    因此比较通用的表达式:

    execution( com.qc..Service.save(..))*

    aop注解开发

    给切面添加@Aspect,编写增强的方法,使用通知类型注解声明

        <!--    开启注解扫描-->
        <context:component-scan base-package="com.qc"/>
    
        <!--    开启自动代理-->
        <aop:aspectj-autoproxy/>
    
    @Aspect
    @Component
    public class MyAspect {
        // 自定义切面类 = 切入点+通知
        //通知
        @Before("execution(* com.qc.*.*.*ServiceImpl.save(..))")
        public void log1() {
            System.out.println("前置增强的");
        }
    
        @AfterReturning("execution(* com.qc.*.*.*ServiceImpl.save*(..))")
        public void log2() {
            System.out.println("后置增强的");
        }
    
        @AfterThrowing("execution(* com.qc.*.*.*ServiceImpl.save*(..))")
        public void log3() {
            System.out.println("异常增强的");
        }
    
        @After("execution(* com.qc.*.*.*ServiceImpl.save*(..))")
        public void log4() {
            System.out.println("最终增强的");
        }
    
        @Around("execution(* com.qc.*.*.*ServiceImpl.save*(..))")
        public void aroundLog(ProceedingJoinPoint point) {
            try {
                log1();
                point.proceed(); // 目标方法调用
                log2();
            } catch (Throwable e) {
                e.printStackTrace();
                log3();
            } finally {
                log4();
            }
        }
    }
    

    在每个方法上使用注解进行配置,和配置文件类似

    通知类型注解:

    1. @Before 前置注解
    2. @AfterReturning 后置注解
    3. @AfterThrowing 异常注解
    4. @After 最终注解
    5. @Round 环绕注解

    注意:在配置文件中开启自动代理

    aop纯注解开发

    @EnableAspectJAutoProxy 开启自动代理

  3. Di(依赖注入)

    依赖注入:在spring框架负责创建bean对象时,动态的将对象注入到其他的bean对象中

    1)属性的set方法注入值的方式

    1. 声明变量并在需要依赖注入的地方设置set方法

    2. 在xml文件中配置该变量的值

          <bean id="us" class="com.qc.service.impl.UserServiceImpl">
              <property name="userDao" ref=""></property>
              <property name="name" value=""></property>
          </bean>
      

      参数说明:如果property中的是一个简单类型(基本类型和字符串),那么就使用value,否则就使用ref

    2)构造方法赋值的方法

    1. 在需要的地方添加构造方法

    2. 在配置文件中使用带参数的构造方法传参

          <bean id="userDao" class="com.qc.dao.impl.UserDaoImpl"></bean>
          <bean id="us" class="com.qc.service.impl.UserServiceImpl">
              <constructor-arg name="userDao" ref="userDao"></constructor-arg>
          </bean>
      
    3. 其他类型的参数传参

      准备一个java类

      public class CollectionBean {
          private String[] strs;
          private List<String> list;
          private Map<String, String> map;
          private Properties properties;
      
          public Properties getProperties() {
              return properties;
          }
      
          public void setProperties(Properties properties) {
              this.properties = properties;
          }
      
          public Map<String, String> getMap() {
              return map;
          }
      
          public void setMap(Map<String, String> map) {
              this.map = map;
          }
      
          public String[] getStrs() {
              return strs;
          }
      
          public List<String> getList() {
              return list;
          }
      
          public void setList(List<String> list) {
              this.list = list;
          }
      
          public CollectionBean() {
          }
      
          public void setStrs(String[] strs) {
              this.strs = strs;
          }
      
          public CollectionBean(String[] strs) {
              this.strs = strs;
          }
      }
      
      1. 不可变数组

        <bean id="co" class="com.qc.service.CollectionBean">
                <property name="strs">
                    <array>
                        <value>小美</value>
                        <value>小张</value>
                        <value>小王</value>
                    </array>
                </property>
            </bean>
        
      2. 可变集合

            <bean id="co" class="com.qc.service.CollectionBean">
                <property name="list">
                    <list>
                        <value>张三</value>
                        <value>李四</value>
                        <value>王五</value>
                    </list>
                </property>
            </bean>
        
      3. map集合

        <bean id="co" class="com.qc.service.CollectionBean">
                <property name="map">
                    <map>
                        <entry key="name" value="zhangsan"></entry>
                        <entry key="age" value="18"></entry>
                    </map>
                </property>
            </bean>
        
      4. 其他类型

          <bean id="co" class="com.qc.service.CollectionBean">
                <property name="properties">
                    <props>
                        <prop key="username">zhangsan</prop>
                        <prop key="password">1234</prop>
                    </props>
                </property>
            </bean>
        
  4. 多配置文件

    1. 在配置文件中使用

      <import resource="applicationContext.xml"></import>
      
    2. 创建工厂时直接加载多个配置文件

              ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext1.xml");
      

标签:配置文件,spring,void,通知,aop,ioc,public
From: https://www.cnblogs.com/ning23/p/18232927

相关文章

  • springMvc 配置 UReport2
    参考:https://blog.csdn.net/qq_42207808/article/details/112258835 1.配置pom.xml引入目前最新得2.2.9版本<dependency><groupId>com.bstek.ureport</groupId><artifactId>ureport2-console</artifactId&......
  • 基于SpringBoot的秒杀系统源码数据库
    基于SpringBoot的秒杀系统源码数据库社会发展日新月异,用计算机应用实现数据管理功能已经算是很完善的了,但是随着移动互联网的到来,处理信息不再受制于地理位置的限制,处理信息及时高效,备受人们的喜爱。本次开发一套基于SpringBoot的秒杀系统,管理员功能有个人中心,用户管理,商品类......
  • 基于springboot的二手车交易系统源码数据库
    基于springboot的二手车交易系统源码数据库如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统二手车交易信息管理难度大,容错率低,管理人员处理数据费工费时,所以专门为......
  • 基于springboot的纺织品企业财务管理系统源码数据库
    基于springboot的纺织品企业财务管理系统源码数据库在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对纺织品企业财务信息管理的提升,也为了对纺织品企业财务信息进行......
  • 一个基于 React + SpringBoot 的在线多功能问卷系统(附源码)
    简介:一个基于React+SpringBoot的在线多功能问卷系统前端技术栈:React、React-Router、Webpack、Antd、Zustand、Echarts、DnDKit后端技术栈:SpringBoot、MySQL、MyBatisPlus、Redis项目源码下载链接: https://pan.quark.cn/s/2e32786e0c61部分页面静态预览: 主要前......
  • 基于springboot实现疫情信息管理系统项目【项目源码+论文说明】计算机毕业设计
    基于springboot实现疫情信息管理系统演示摘要近年来,信息化管理行业的不断兴起,使得人们的日常生活越来越离不开计算机和互联网技术。首先,根据收集到的用户需求分析,对设计系统有一个初步的认识与了解,确定疫情信息管理系统的总体功能模块。然后,详细设计系统的主要功能模块,通......
  • 128springboot汽车租赁管理系统租车订单还车汽车资讯论坛管理(源码+文档+PPT+运行视频+
    项目技术:springboot+Maven+Vue等等组成,B/S模式+Maven管理等等。环境需要1.运行环境:最好是javajdk1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;3.tomcat环境:Tomcat7.x,8.x,9.x版本均可4.硬件环境:windows......
  • SpringBoot+微信支付-JSAPI{微信支付回调}
    引入微信支付SDKMaven:com.github.wechatpay-apiv3:wechatpay-java-core:0.2.12Maven:com.github.wechatpay-apiv3:wechatpay-java:0.2.12响应微信回调的封装@Getter@Setter@NoArgsConstructor@AllArgsConstructor@Accessors(chain=true)publicclassWxNotifyVo{......
  • springboot如何去自定义端口
    springboot如何去自定义端口https://blog.csdn.net/m0_63102097/article/details/138584857 1.在application.properties文件中设置端口号:server.port=80802.在application.yml文件中设置端口号:   server:     port:80803.通过命令行参数指定端口号启动应用程序:jav......
  • 毕业设计-基于Springboot+Vue的影城管理系统的设计与实现(源码+LW+包运行)
    如需完整项目,请私信博主基于SpringBoot+Vue的影城管理系统开发语言:Java数据库:MySQL技术:SpringBoot+MyBatis+Vue.js工具:IDEA/Ecilpse、Navicat、Maven互联网发展至今,已经解决了很多我们解决不了的难题,使得我们工作更加便捷,提高了我们的工作效率。目前各行各业都在运用网络信......