目录
Spring
@BeforeEach 在执行@Test方法前调用. 是测试方法提供的测试API.
@Configuration 将当前类标识为配置类
@Bean 将方法的返回值,交给Spring容器管理.
1.xml形式
<bean id="user" class="com.jt.demo.User"></bean>
spring容器管理对象
ApplicationContext容器顶级接口
ClassPathXmlApplicationContext 加载配置文件的实现类对象
2.注解形式
Map集合的结构 Map<方法名,方法的返回值>
容器对象
ApplicationContext容器顶级接口
AnnotationConfigApplicationContext
@Component 将当前的类,交给Spring容器管理, 对象的创建是由Spring通过反射机制自动创建对象.
@ComponentScan(“com.jt”) 指定扫描的包路径, 可以扫描它的子孙包,用在配置类中
@Scope("singleton") 默认值 单例模式
@Scope("prototype") 多例模式
@Lazy 添加表示改为懒加载【 主要测试对象中的无参构造什么时候执行】
@PostConstruct 在对象创建之后立即调用
@PreDestroy 对象消亡时 进行调用
@Autowired 可以将Spring容器中的对象,自动注入到属性中.
注入方式:
1. 默认按照类型注入. 如果注入的属性是接口,则自动注入实现类
2. 按照名称注入(key). 一般不用
@Qualifier("cat") 接口多实现【该注解不能单独使用,必须配合Autowired使用,根据key进行注入】
@Resource(name="dog") 功能上说,相当于 @Autowired + @Qualifier("cat")
@Controller 控制层 Controller 与前端页面交互的. 【只有类 不用写接口】
@Service 业务层 Service 编辑业务逻辑.
@Repository(暂时) 持久层 Mapper 实现数据库的相关操作 【为了让程序员开发有层级的概念】
@Value 可以直接为基本类型赋值和String类型
@PropertySource(value="classpath:/user.properties",encoding = "UTF-8")
【classpath: 代表resources的根目录】
(动态代理)代理对象----JDK/CGlib
JDK代理工具API
Proxy.newProxyInstance(类加载器,接口数组,invocationHandler接口)
JDK代理【要求必须有/实现接口. 如果没有接口,则JDK代理不能正常执行.】
JDK代理模式是java原生提供的API,无需导包
JDK代理要求: 被代理者必须 要么是接口,要么实现接口
灵活: 代理对象应该看起来和被代理者 一模一样!!! (方法相同)
1.获取类加载器
ClassLoader classLoader = target.getClass().getClassLoader();
2.获取接口数组类型
Class[] interfaces = target.getClass().getInterfaces();
3.代理对象执行方法时的回调方法(代理对象调用方法时,执行InvocationHandler)
return Proxy.newProxyInstance(classLoader,interfaces,invocationHandler(target));
CGlib代理工具API
Enhancer 增强器对象 获取代理对象 enhancer.create(); 回调接口MethodInterceptor接口
CGlib代理: 【要求被代理者有无接口都可以. 代理对象是目标对象的子类 重写子类方法】
1.创建增强器对象
Enhancer enhancer = new Enhancer();
2.设定父级 目标对象
enhancer.setSuperclass(target.getClass());
3.定义回调方法 代理对象执行目标方法时调用
enhancer.setCallback(getMethodInterceptor(target));
4.创建代理对象
return enhancer.create();
AOP
@EnableAspectJAutoProxy 开启AOP
@EnableAspectJAutoProxy(proxyTargetClass = true) JDK代理修改为cglib代理
@Aspect 标识该类是一个切面
@Pointcut 切入点表达式
1、bean表达式【根据bean的ID拦截指定的对象.】【当调用的方法是指定的bean的方法时生效。】
@Pointcut("bean(userServiceImpl)")
2、within表达式【 按照类型匹配. 可以使用通配符*号】【指定某些类型的全部方法执行,也可用来指定一个包。】
1. @Pointcut("within(com.jt.service.UserServiceImpl)")
只拦截UserServiceImpl的类
2. @Pointcut("within(com.jt.service.*)")
拦截com.jt.service下的一级的类.
3. @Pointcut("within(com.jt.service..*)")
拦截com.jt.service下所有包下的所有类
4. @Pointcut("within(com.*.service..*)")
拦截com.任意包.service下所有包下的所有类
3、execution表达式【一般用于指定方法的执行,用的最多。】
语法: @Pointcut("execution(返回值类型 包名.类名.方法名(参数列表))")
1. 按照类型方法匹配
@Pointcut("execution(* com.jt.service.UserServiceImpl.addUser())")
2. 要求返回值任意, com.jt.service包下的所有的子孙类中的任意方法的任意参数要求拦截.
@Pointcut("execution(* com.jt.service..*.*(..))")
3. 要求返回值任意, com.jt.service包下的所有的子孙类中的add开头的方法并且参数1个是int类型 进行拦截
@Pointcut("execution(* com.jt.service..*.add*(int))")
4、@annotation表达式【可以根据用户的自定义注解进行拦截】【当执行的方法上拥有指定的注解时生效。】
1、完成自定义注解
@Retention(RetentionPolicy.RUNTIME) 注解运行期有效
@Target(ElementType.METHOD) 注解标识 方法
public @interface Lyj {}
2、标记注解(标记在Service被代理类的目标方法上)
3、AOP拦截注解
@Ponitcut("@annotation(com.jt.anno.Lyj)")
AOP五大通知
1.前置通知
在目标方法执行之前执行.
@Before("pointcut()")
public void before(){
System.out.println("我是前置通知!!!!");
}
用法:
@Before("pointcut()")
public void before(JoinPoint joinPoint){//连接点:获取方法中的数据
Class targetClass = joinPoint.getTarget().getClass();
String methodName = joinPoint.getSignature().getName();
String className = joinPoint.getSignature().getDeclaringTypeName();
Object[] objs = joinPoint.getArgs();
System.out.println("我是前置通知!!!!");
System.out.println("类型:"+ targetClass);
System.out.println("方法名称:"+methodName);
System.out.println("类的名称:"+className);
System.out.println("方法中携带的参数:"+ Arrays.toString(objs));
}
2.后置通知
在目标方法执行之后执行
@AfterReturning("pointcut()")
public void afterReturn(){
System.out.println("我是后置通知!!!!");
}
用法:
需求: 记录一下用户目标方法的返回值
说明: 通过属性returning 获取方法的返回值
//通过returning = "result"属性,获取目标方法的返回值,当作参数传递给result
@AfterReturning(value = "pointcut()",returning = "result")
public void afterReturn(Object result){
System.out.println("我是后置通知!!!!");
System.out.println("用户的返回值为:"+result);
}
3.异常通知
目标方法执行报错时,执行该通知
@AfterThrowing("pointcut()")
public void afterThrowing(){
System.out.println("我是异常通知!!!!");
}
用法:
【如果用户执行业务方法时,报错了,则可以使用异常通知记录日志.】
@AfterThrowing(value = "pointcut()",throwing = "exception")
public void afterThrowing(Exception exception){
System.out.println("我是异常通知!!!!");
System.out.println("获取异常信息:"+exception.getMessage());
exception.printStackTrace();
}
4.最终通知
目标方法之后都要执行的通知
@After("pointcut()")
public void after(){
System.out.println("最终通知都要执行");
}
5.环绕通知
(重点掌握)在目标方法执行前后都要执行,控制目标方法
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知执行前!!!!");
//底层调用动态代理的invoke方法,执行目标方法
Object result = joinPoint.proceed();
System.out.println("环绕通知执行后!!!!");
return result;
}
@Order 实现切面的排序
SprngMVC-----前后端交互
@SpringBootApplication 主启动项
(相当于@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan)
@EnableAutoConfiguration 启动自动化的配置
@ResponseBody 将返回值转化为JSON串
@RequestMapping("/findJSON") 映射
@RestController 相当于 @Controller + @ResponseBody【将当前类的所有返回值都转化为JSON】
@CrossOrigin 允许跨域【主要解决跨域问题】
@PostMapping("/saveUser")
@GetMapping
@PutMapping
@DeleteMapping
Axios--Spring【lombok的使用】
@Data Getter/Setter/RequiredArgsConstructor/ToString/EqualsAndHashCode
@Accessors(chain = true) 重写了set方法. 可以实现链式加载
@NoArgsConstructor 无参构造方法
@AllArgsConstructor 全参构造方法
@SpringBootTest 测试类启动,Spring容器启动(通过测试方法,可以自己调用,测试代码是否正确)
@Mapper 将接口交给Spring容器管理Map<userMapper,JDK代理对象>
缓存
@Transactional(rollbackFor=Exception.class)
一级缓存---事务注解 使用同一个SqlSession
@CacheNamespace
二级缓存注释(xml配置文件 不能同时生效)--同一个SqlSessionFactory内部有效.
Myatis-plus
@TableName("user") 让对象与表名 一一映射
@TableId(type = IdType.AUTO) 标识主键
@TableField("username") 如果属性与字段名称一致(包含驼峰规则),则注解可以省略
@TableField(fill = FieldFill.INSERT)
@TableField(fill = FieldFill.INSERT_UPDATE)