spring5学习笔记其一

1.bean对象成员属性赋值

注入bean对象时,需要写出类的set方法,底层也是基于这个set函数来给类的成员属性赋值的。


2.有其它类作为该类的成员属性

通过xml形式来配置bean对象时,当一个类中,有其他类的对象做成员属性时,可以使用ref外部bean对象或者property注入内部对象的方式来描述。


3.注入属性注意事项

当通过

<property name="address" value="贵州省安顺市"/>

这样注入属性值时,需要在类中写出对应属性的set方法,不然会出错。


4.级联赋值

<bean id="empEntity" class="com.lzx.entity.EmpEntity">
        <property name="name" value="lzx"/>
        <property name="address" value="贵州省安顺市"/>

        <property name="deptEntity" ref="deptEntity"/>
        <property name="deptEntity.name" value="IT部门"/>
    </bean>
    <bean id="deptEntity" class="com.lzx.entity.DeptEntity"/>

级联赋值注入集合:

<bean id="stuEntity" class="com.lzx.entity.StuEntity">
        <property name="list">
            <list>
                <value>lzx</value>
                <value>yy</value>
            </list>
        </property>
        <property name="arrays">
            <array>
                <value>我爱你</value>
                <value>非常爱你</value>
            </array>
        </property>

        <property name="map">
            <map>
                <entry key="67" value="a"></entry>
            </map>
        </property>

        <property name="set">
            <set>
                <value>666</value>
                <value>777</value>
                <value>666</value>
            </set>
        </property>
    </bean>

注入的list类型为对象的:

在StuEntity中有List<CourseEntity> courses;

<property name="courses">
            <list>
                <ref bean="courseEntity"/>
            </list>
        </property>
<bean id="courseEntity" class="com.lzx.entity.CourseEntity">
        <property name="name" value="Java"/>
    </bean>

5. 在spring的配置文件中对集合统一配置

对list提取出公共配置,在spring的配置文件中,若该对象有多个list属性,并且list的值有公共部分,注入属性值比较麻烦,可提取出来。

需要对sping.xml文件修改一下头部(目的是使用util标签):

<?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:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util.xsd">
<util:list id="list">
    <value>lzx</value>
    <value>yy</value>
</util:list>
    <!-- 配置注入spring bean对象
    id命名一般为类名的首字母小写
    class
    -->
    <bean id="stuEntity" class="com.lzx.entity.StuEntity">
<property name="list" ref="list"/>
    </bean>

</beans>

6. IOC操作bean管理

package com.lzx.factorybean;

import org.springframework.beans.factory.FactoryBean;

public class MyFactoryBean implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
        return new Object();
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }
}

底层是在类中自己实现需要返回哪个类。在spring的bean配置文件中也需要正常配置该实现了FactoryBean类的类


7.spring中bean的作用域

单例配置:

<bean id="userEntity" class="com.mayikt.entity.UserEntity" scope="singleton"></bean>

多例配置:

<bean id="userEntity" class="com.mayikt.entity.UserEntity" scope="prototype"></bean>

默认为单例。


8. springbean的生命周期

对象的创建与销毁的过程,类似之前学习servlet生命的周期过程。

生命周期的原理:

  1. 通过构造函数创建bean对象(默认执行无参构造函数 底层基于反射实现)
  2.  为bean的属性设置 (使用反射调用set方法)
  3. 调用bean的初始化的方法(需要单独在类中配置初始化的方法)
  4.  正常使用bean对象
  5.  Spring容器关闭,调用该类的销毁回调的方法(需要单独在类中配置销毁的方法)

还需要在spring的bean配置文件中写上:

<bean id="memberEntity" class="com.mayikt.entity.MemberEntity" init-method="initMethod" destroy-method="destroyMethod">
   <property name="name" value="mayikt"></property>
</bean>
<bean id="mayiktBeanPost" class="com.mayikt.bean.MayiktBeanPost"></bean>

9.springbean的生命周期核心

springbean的生命周期核心---后置处理器(BeanPostProcessor):

在init方法之前和之后执行。通过实现BeanPostProcessor接口,重写两个方法。

在springbean配置文件中定义了后置处理器的bean后,那么该配置文件的所有bean都是需要走该后置处理器。配置后置处理器和配置常规类是一样的。

一个bean对象可以走多个后置处理器,当有多个后置处理器时,可以在后置处理器中实现Ordered接口,再重写getOrder方法,返回值越小越先执行。


10spring自动装配bean

在xml文件配置中,autowire属性配置,有两个值,byName是在类中的属性名称匹配xml文件中的其它bean,若相同则自动赋值。byType就是看其它bean的class类型与成员属性的类型有没有相同的,有就自动赋值。


11. Java反射技术

 

 class.forName()初始化对象。在需要使用该对象时,才会使用类加载器的方法来加载.class文件到内存中。

三种获取类的方式:

 还可以通过获取到的该类,来调用到类中的所有方法,包括私有、公有,也可以为变量设置值,也是包括私有和公有。


12.spring中的AOP技术

基于代理设计模式封装。

代理设计模式又分为静态代理和动态代理。

动态代理又分为jdk动态代理和cglib动态代理。

将重复的代码单独放到一个类中,再在这个类中调用其它类的目标方法。

比如在目标方法前后开启事务、在目标方法前后输出日志。

静态代理设计模式的实现(使用于类少):

一个接口、该接口的实现类、代理类,客户端。四个文件实现。

可以通过实现接口的方式实现、可以通过继承接口的实现类来实现(该方法用得很少,Java不支持多继承)。

更多使用JDK动态代理或者cglib代理:

 使用JDK动态代理来实现Mybatis中的mapper。

cglib动态代理:

 代理类直接继承接口的实现类


13. AOP详解

AOP, 或者面向切面编程(Aspect-Oriented Programming),是一种软件开发的编程思想和方法论。它的目标是将横切关注点(如日志记录、事务管理、安全性等)与核心业务逻辑相分离,从而提高代码的可维护性和重用性。

在AOP中,横切关注点被称为切面(Aspect),切面通过定义一些特定的通知(Advice),在程序的不同位置被织入到被称为连接点(Join Point)的代码位置上。通知可以在连接点之前、之后或者环绕连接点执行。

AOP的一个重要概念是切点(Pointcut),切点用于定义在哪些连接点上应该执行特定的通知。切点使用一种特定的表达式语言来描述连接点的选择。

AOP提供了一种更加灵活的编程方式,可以在不修改核心业务逻辑的情况下,很方便地添加和管理横切关注点。它广泛应用于日志记录、事务管理、权限控制等领域。

总结来说,AOP是一种面向切面的编程思想,通过将横切关注点与核心业务逻辑分离,提高了代码的可维护性和重用性。

前置通知、后置通知、异常通知、环绕通知。

@AfterReturning 表达后置通知注解。在目标方法返回结果后执行。

异常通知:目标方法抛出异常后才会通知。

package com.lzx.proxy;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @author 梁志雄
 * @date 2023/8/9 15:51
 */

@Component   //加上该注解,相当于在xml文件中配置了bean,自动加入spring的IOC容器中。
@Aspect  //定义切面
public class UserProxy {

    //前置通知、后置通知、环绕通知、异常通知
    //@Before(value = "execution(* com.lzx.service.LzxService.*(..))")  //定义切入点
    //public void beforeNotification(){
    //    System.out.println("在目标方法之前执行...");
    //}
//
    //@After(value = "execution(* com.lzx.service.LzxService.*(..))")
    //public void afterNotification(){
    //    System.out.println("在目标方法之后执行...");
    //}

    @Around(value = "execution(* com.lzx.service.LzxService.*(..))")
    //环绕通知可以获取到当前目标的信息
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕通知前...");
        Object result = proceedingJoinPoint.proceed(); //调用目标方法的返回结果(也即目标方法的返回结果)
        System.out.println("环绕通知后...");
        System.out.println(result+"环绕通知");
    }

    @AfterThrowing(value = "execution(* com.lzx.service.LzxService.*(..))")
    public void afterThrowing(){
        System.out.println("异常通知,在方法抛出异常时执行。");
    }
}

spring的AOP底层基于代理模式封装。使用的cglib

如果被代理类有接口,那么就是使用的JDK动态代理。

如果没有,默认走cglib动态代理。

在前置通知中,可使用API来获取到目标方法传入的参数:

@Before(value = "execution(* com.lzx.service.LzxService.*(..))")  //定义切入点
    public void beforeNotification(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        System.out.println(Arrays.toString(args));
        System.out.println("在目标方法之前执行...");
    }

@PointCut注解定义切入点。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jay/.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值