实体类相关:
@Data //生成set、get、toString、equals、hashCode等方法
@AllArgsConstructor //生成带参构造方法
@NoArgsConstructor //生成无参构造方法
@Component //交由Spring的IOC容器来创建对象
public class Student {
private Long studentId;
private String studentName;
private String studentSex;
@JSONField(format = "yyyy-MM-dd") //将pojo对象转json时指定时间类型要转的格式
//@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date studentBornDate;
private String studentImg;
private StudentClass studentClass;
}
//需要使用lombok依赖
@Data
@AllArgsConstructor
@NoArgsConstructor
//需要使用fastjson的依赖
@JSONField(format = "yyyy-MM-dd")
Spring 有两大核心:IOC 和 AOP IOC 即控制翻转,通常我们在项目当中需要手动 new 去创建对象,这种方式不利于对对象的管理,现在我们将对象的创建权利翻转给 spring 容器,这就是控制翻转。spring 容器在实例化对象的时候,会根据对象直接的依赖关系,自动完成属性注入工作,这就是依赖注入。 AOP 即面向切面编程,底层是通过动态代理的机制来实现的,支持 jdk 和 cglib 两种。 默认通过 jdk 动态代理。通常我们在项目当中,一些公共功能的实现可以通过 aop 来进行解耦和统一实现,例如:事务管理、日志、权限等。
Spring的IOC容器注解:
交由Spring的IOC容器去创建并管理对象
@Repository //在Mapper层交由IOC创建EmpMapper对象
public class EmpMapperMySQLImpl implements EmpMapper {
@Override
public List<Emp> getAllEmp() {
System.out.println("mysql的方法");
return null;
}
}
@Controller //在控制器层交由IOC容器去创建对象
public class TestController {
}
@Service("empService") //在Service层交由IOC创建EmpService对象
public class EmpServiceImpl implements EmpService {
@Autowired //自动装配属性
//当存在两个一样的类型时,会先按照名称去找
//如果名称找不到的话,自动装配就不知道要装配哪个,使用这个注解指定那个
//这里就是两个实现类,都是EmpMapper的类型的实现类,如果需要使用的话就要指定
@Qualifier("empMapperMySQLImpl")
//Resource 默认按照byName自动装配,如果装配失败按照byType装配属性
private EmpMapper empMapper; //相当于类的属性
//@Resource 首先按照byName找,然后按照byType找
//@Resource(name = "empMapper") 可以找指定名字的,如果找指定名字的,找不到也不会再按照byType找,因为已经指定了按照名字找
@Resource(name = "empOracle")
private EmpMapper empMapper2;
@Override
public List<Emp> getAllEmp() {
empMapper2.getAllEmp();
return empMapper.getAllEmp();
}
}
//默认的名字是类名,首字母改成小写
//可以修改名字,直接在注解里面写括号,双引号里面直接写新的名字即可
//写完注解不可以直接使用的,需要写配置文件 让springIOC容器去扫描指定的位置(扫描到带注解的类就可以使用了),才可以
// <context:component-scan base-package="com.lcz"/>
@Component("emmp") //除了Service层、Mapper层、Controller层其他层需要IOC去管理对象的话使用这个注解
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {
@Value("123") //可以使用Value这个注解直接给属性赋值
private Integer empId;
private String empName;
private String gender;
@Autowired //这里的自动装配是根据类型而不是根据名字装配,而且装配是优先选择注解(同类型,有注解,有xml配置,选择注解)
private Dept dept;
}
四个注解,分别管理不同层的对象:(需要添加Spring的依赖)
@Controller //Controller层
@Repository //Mapper层
@Service //Service层
@Component //除以上之外的层
AOP的注解:
package com.licz.annotation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component //这个对象交由Spring的IOC容器去创建
@Aspect //方法增强注解,除此之外还需要添加配置:(配置如下)
public class EmpServiceAspectj {
//可以定义一个公共的,定义一处,多处使用
@Pointcut("execution( * com.licz.annotation.EmpService.addEmp(com.licz.aop.Emp))")
//增强的方法:public void addEmp(Emp emp) {
public void pointCut() {
}
//使用的时候调方法名即可
@Before("pointCut()")
public void beforeHandle(JoinPoint joinPoint) {
System.out.println("方法名" + joinPoint.getSignature().getName());
System.out.println("目标对象" + joinPoint.getTarget());
System.out.println("方法参数" + Arrays.toString(joinPoint.getArgs()));
System.out.println("打开连接");
}
//无论是否出现异常,都会执行
@After("execution( * com.licz.annotation.EmpService.addEmp(com.licz.aop.Emp))")
public void afterHandle() {
System.out.println("目标方法之后执行的方法");
}
@AfterReturning("execution( * com.licz.annotation.EmpService.addEmp(com.licz.aop.Emp))")
public void returnningHandle() {
System.out.println("目标方法执行成功之后执行此处。。。。");
}
@AfterThrowing(value = "execution( * com.licz.annotation.EmpService.addEmp(com.licz.aop.Emp))", throwing = "ex")
public void exceptionHandle(Exception ex) {
System.out.println("目标方法执行异常后执行这里,异常日志:" + ex);
}
//环绕增强:前面所有的注解功能,这里都可以实现
@Around(value = "execution( * com.licz.annotation.EmpService.addEmp(com.licz.aop.Emp))")
public Object aroundHandle(ProceedingJoinPoint proceedingJoinPoint) {
//注意:方法增强是在原方法不变的基础上,对功能进行增强,如果有一个功能:
//登录功能:原方法,登录查询,返回一个pojo类型,不为null登录成功,null登录失败
//如果这里做增强,返回值为boolean类型,在目标方法后的增强,那么原方法的返回值就会由pojo改为boolean,
//因为是目标方法执行完之后执行增强方法,返回值类型就会以后执行的为准
try {
System.out.println("之前会执行的方法");
// 执行目标方法
Object proceed = proceedingJoinPoint.proceed();
System.out.println("之后会执行的方法");
return proceed;
} catch (Throwable e) {
System.out.println("目标方法异常执行这里:异常:" + e);
} finally {
// 一定会执行的方法
System.out.println("关闭连接");
}
return null;
}
}
配置:application-context.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: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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--使用注解创建对象的话要开启组件扫描-->
<context:component-scan base-package="com.licz.annotation"/>
<!--
对象是由Spring的IOC容器创建的,而这个增强功能是aspectj提供的
让spring认识aspectj
-->
<aop:aspectj-autoproxy/>
</beans>
事务:
使用注解:
package com.lcz.service.impl;
import com.lcz.mapper.AccountMapper;
import com.lcz.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service //注解的方式 创建IOC容器中的accountService对象
public class AccountServiceImpl implements AccountService {
@Autowired //自动装配对象,装配到IOC容器中,是根据byType识别的对象
private AccountMapper accountMapper;
@Override
@Transactional //事务:如果全部SQL中有SQL执行异常,自动回滚,如果全部执行成功,则提交
public void updateAccountMoney(Integer outAccountId, Integer inAccountId, Double money) {
accountMapper.updateAccount(outAccountId, -money);
int a = 10 / 0; //此处有异常,事务会进行回滚
accountMapper.updateAccount(inAccountId, money);
}
}
配置:application-context.xml
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--开启事务注解 这是使用注解的方式 注解是在Service的实现类的对应方法上加上@Transactional-->
<tx:annotation-driven transaction-manager="transactionManager"/>
使用配置文件:推荐使用
以配置的方式实现事务,可以配置完之后无需额外的注解,一处配置,全部使用
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--以配置的方式实现事务,可以配置完之后无需额外的注解,一处配置,全部使用-->
<!--配置事务的属性-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--匹配的是Service层的方法名,这里就是以add开头的方法,当有异常时就回滚-->
<tx:method name="add*" rollback-for="Exception"/>
<tx:method name="remove*" rollback-for="Exception"/>
<tx:method name="modify*" rollback-for="Exception"/>
<tx:method name="find*" read-only="true"/>
<!--Service层的所有方法,有异常时就回滚,可能有一些方法名前缀不是add、remove、等的-->
<tx:method name="*" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!--配置aop增强,用到增强的话就需要加入spring-aspects的依赖-->
<aop:config>
<!--配置增强的切点,* com.lcz.service.impl.*.*(..) 指的是所有修饰符返回值下的impl包下的所有类的所有方法,不管什么参数(可变参数)-->
<aop:pointcut id="pointCut" expression="execution(* com.lcz.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>
Maven中的依赖缺一不可,否则项目会启动报错