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
<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生命的周期过程。
生命周期的原理:
- 通过构造函数创建bean对象(默认执行无参构造函数 底层基于反射实现)
- 为bean的属性设置 (使用反射调用set方法)
- 调用bean的初始化的方法(需要单独在类中配置初始化的方法)
- 正常使用bean对象
- 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注解定义切入点。
还没有评论,来说两句吧...