1.beans.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
2.beans.xml中bean的创建
创建bean时默认识别无参构造方法,所以我们要附加相应的属性才能让编辑器识别其他构造方法。
创建bean我们主要使用三种方法。(例子为下)
属性一定要加set方法,否则无法执行<property>中的语句。
<!--使用Spring创建对象-->
<!-- 默认使用无参构造-->
<bean id="hello" class="com.huang.pojo.hello">
<!-- value是为该创建对象的属性值-->
<property name="str" value="Spring111"/>
</bean>
<!-- <property name="str" ref=""/> ref引用Spring中已创建好的对象-->
<bean class="com.huang.pojo.User" id="UserData">
<!-- <constructor-arg type="java.lang.String" value="hfwen"/> 使用类型识别构造器-->
<!-- 通过对应的index序号来识别对应的构造器-->
<constructor-arg index="0" value="hfwen"/>
</bean>
<!-- 使用参数的name来识别对应的构造器-->
<bean id="UserDao" class="com.huang.pojo.User">
<constructor-arg name="name" value="hfw"/>
</bean>
3.依赖注入
依赖注入分为:构造器注入, set注入,拓展注入。
构造器注入:通过不同的构造器创建不同的类从而产生注入。
set注入:通过对被创建类中的属性进行赋值从而产生注入。
拓展方式注入: 就是 p命名和 c命名从而产生注入。(p命名和c命名不能直接使用,需要导入xml约束)
c命名的引入代码为下
xmlns:c="http://www.springframework.org/schema/c"
p命名引入代码为下:
xmlns:p="http://www.springframework.org/schema/p"
通过util 提取list。(例子为下)
FactoryBean :器特点是返回类型可以不是类名。通过实现FactoryBean接口实现。
设置实例的单例和多例
singleton和prototype的区别
4.bean的自动装配&IOC
自动装配: 通过@Autowrited等注解,实现自动装配对应的属性值。
autowire="byName"
需要保证所有的bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致。(通过对应的名字进行自动装配)
autowire="byType"
需要保证所有的bean的class唯一,并且这个bean需要和自动注入的属性的类型的值一致。(对应的对象类型要唯一,不然会出错)
IOC (控制反转): 在没有IOC的程序中,我们使用面向对象编程,对象的创建于对象间的依赖关系完全硬编码在程序中,对象的创建由自己控制。而控制反转后将对象的创建转移给第三方,所谓的控制反转就是:获得依赖对象的方法反转了。
IOC的最大作用是:解耦合。
5.使用注解开发
注解适用于简单的配置,复杂的配置还是走配置文件,以便于后期维护。
要使用注解须知:
1.导入约束。
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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
@Autowired:自动装配,可以理解成autowire:byType。 @Scope:配置模式。 @Autowired(required = false)说明这个对象可以为空,否则不能为空。 @Nullable:用于存放方法的参数,表示参数可以为null。 @Qualifier(value = ""):可以理解成autowire:byName,value表示Name。 @Component:组件,放在类上,说明这个类被Spring管理了等价于:<bean id = "XXXX" class = "XXX"/>,默认创建的类名为该类的名字的小写。 @value用于对类中的属性进行赋值。 对应的例子为下:
@Component
public class User {
// 等价于<property name = "name" value = "张三">
@Value("张三")
public String name;
}
@Component有一些衍生注解,在我们web开发中,会以MVC三层架构进行分层。
- Dao[@Repository]
- Service[@Service]
- Controller[@Controller]
这四个注解的功能都是一样的,都代表某个类注册到Spring中,装配bean。
如果@AutoWired自动装配环境比较复杂,自动装配无法通过一个注解[@AutoWired]完成的时候,我们可以使用@Qualifier(value = "XXX")去配合@AutoWired的使用,指定一个唯一的bean对象注入!
例子如下:
@Autowired
private Cat cat;
@Autowired
@Qualifier(value = "dog222")
private Dog dog;
@Resource也可以实现自动装配,其装配的过程为:先查看对应的name,而后再查看class,如果两个属性都不符合的话就会报错。
(重点)@Resource和@AutoWired的区别:
1.都是用自动装配的,都可以放在属性字段上。
2.@AutoWired通过byType的方式实现,而且必须要求这个对象存在。(不会像@Resource一样在找不到时以另种方式进行查找)
3.@Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的话就会报错。
开启注解扫描:
6.使用java配置Spring
使用的类为:
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext("类");
格式:
//这里这个注解的意思是:说明这个类被Spring接管了,注册到了容器里了
//等价于:<bean id = "user" class = "User"><property name = "name" value = "张三"></bean>
@Configuration//这个也会被Spring接管,因为@Configuration本来就是@Component,@Configuration表示这是一个配置类,其功能和bean.xml相同
public class User {
private String name;
public String getName() {
return name;
}
@Value("张三")
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
//注册一个bean,相当于bean标签
//这个方法的名字相当于bean中的id
//这方法的返回值相当于bean中的class
@Bean
public User getUser(){
return new User();//返回要注入到bean容器中的对象
}
}
所以这个配置类可以做和bean.xml中相同的事。
@ComponentScan :用于扫描类。
AOP
要使用Aop就要在pom.xml中导入对应的依赖。
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
提供声明式业务,允许用户自定义切面。
Spring 实现 AOP的方式
1.使用Spring的api接口:
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.huang.service.UserServiceImpl"/>
<bean id = "log" class="com.huang.log.Log"/>
<bean id="alterLog" class="com.huang.log.afterLog"/>
<!-- 配置aop-->
<!-- 方式一:使用原生的api接口-->
<aop:config>
<!--需要一个切入点 expression为表达式,execution(要执行的位置!)-->
<!-- execution(* com.huang.service.UserServiceImpl.*(..))表达式的意思是:com.huang.service.UserServiceImpl
下面的所有文件,(..)表示可以有任意的参数-->
<!--切片位置,给切片位置命名-->
<aop:pointcut id = "pointcut" expression = "execution(* com.huang.service.UserServiceImpl.*(..))"/>
<!-- 执行环绕增强-->
<!-- point-ref为插入位置-->
<!-- 在切片位置要做的事情-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="alterLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>
2.使用自定义类实现aop
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.huang.service.UserServiceImpl"/>
<bean id="diy" class="com.huang.diy.DiyPointCut"/>
<aop:config>
<!--自定义的切面,ref要引用的类-->
<aop:aspect ref="diy">
<!-- 切入点-->
<aop:pointcut id="point" expression="execution(* com.huang.service.UserServiceImpl.*(..))"/>
<!--通知-->
<!-- 设置切入时使用的方法-->
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
</beans>
3.注解实现aop
//使用注解实现aop
@Aspect//标记这是个切面
public class AnnotionPointCut {
@Before("execution(* com.huang.service.UserServiceImpl.*(..))")//写入切入位置
public void before(){
System.out.println("=============方法执行前==========");
}
@After("execution(* com.huang.service.UserServiceImpl.*(..))")//写入切入类位置
public void after(){
System.out.println("=============方法执行后==========");
}
}
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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.huang.service.UserServiceImpl"/>
<bean id="annotationPointCut" class="com.huang.diy.AnnotionPointCut"/>
<!-- 开启注解支持-->
<!-- 自动代理-->
<aop:aspectj-autoproxy/>
</beans>
显然注解是最方便的。
Mybatis的巩固
Mybatis的环境搭建_Ostkakah的博客-CSDN博客
IOC解析
通过下面两个类可以解析xml文件。
IOC容器的两种实现方式:
Bean的生命周期
通过bean的注入连接数据库(Druid)
AOP分析
aop的写法:
通知的类型:
后置通知和最终通知的区别:后置通知会在返回值后和抛出异常后执行,而最终通知只会在有返回值后执行。
抽取相同的表达式:
当存在多个增强类时,我们可以通过@Order来设置优先级,数值越小,优先级就越大。
jdbcTemplate 的查询
返回为对象的写法:
例子:
如果要返回List集合的话,我们就使用query()。(需求参数不变)
批量添加例子:
批量修改例子:
批量删除例子:
配置事务
使用的类为下:
在xml文件中开启事务的注解(需要引入tx的名字空间)
使用时就在对应的类或方法上加@Transactional。
在@Transaction中可配置的参数为下:
1.事务的传播性(Propagation)
重点为:REQUIRED 和 REQUIRED_NEW。
2.事务隔离级别(ioslation)
脏读:事务一修改了表中的一行数据,但没有提交,这时候事务二读取了被事务一修改后的数据,之后事务一因为某种原因回滚,那么事务二读取的数据就是脏的。
不可重复读:不可重复读是事务1操作一条记录的时候,事务2也操作了且提交,事务1再次读就发现数据变了。(update)
幻读(虚读):指一个线程中的事务读取到了另外一个线程中提交的insert的数据。 (insert)
隔离级别越高,效率越低,一般只解决脏读问题。(默认使用可重复读)
timeout: 超时时间。作用:设置在多长时间内进行回滚。(默认为-1,以秒为单位,也就是不回滚)
readOnly: 是否只读。当将其设置为true就只能进行查询操作了。(默认为false)
rollbackFor: 回滚。作用:出现哪些异常时就进行回滚。
noRollbackFor: 不回滚。作用:出现哪些异常时不回滚。
全注解开发:
日志
在log4j2.xml配置。
<?xml version="1.0 encoding="UTF-8"?>
<configuration status="INFO">
<appenders>
<console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</console>
</appenders>
<loggers>
<root level="info">
<appender_ref ref="Console"/>
</root>
</loggers>
</configuration>
日志级别:
手动在日志中添加信息的方法
通过LoggerFactory获取对应的logger,并对此log操作。
@Nullable注解
使用 Junit5
需要使用的注解: