| |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| -> Java知识库 -> 春天 -使 Java简单的、现代的、富有成效、反应性。 -> 正文阅读 |
|
|
[Java知识库]春天 -使 Java简单的、现代的、富有成效、反应性。 |
1. Spring概述1.1 什么是框架?
框架(
Framework
):框(指其约束性)架(指其支撑性),在软件设计中指为解决一个开放性问题而 设计的具有一定约束性的支撑结构。在此结构上可以根据具体问题扩展、安插更多的组成部分,从而更 迅速和方便地构建完整的解决问题的方案。
1、框架本身一般不完整到可以解决特定问题
2、框架天生就是为扩展而设计的
3、框架里面可以为后续扩展的组件提供很多辅助性、支撑性的方便易用的实用工具(utilities), 也就是说框架时常配套了一些帮助解决某类问题的库(libraries)或工具(tools)。
1.2 Spring是什么
Spring
官网
https://spring.io
Spring
被称为
J2EE
的春天,是一个是分层的
Java SE/EE
full-stack
开源
的
轻量级
的
Java
开发框架, 是 最受欢迎的企业级 Java
应用程序开发框架,数以百万的来自世界各地的开发人员使用
Spring
框架来创 建性能好、易于测试、可重用的代码。
Spring
具有
控制反转
(
IoC
)和
面向切面
(
AOP
)两大核心。
Java Spring
框架通过声明式方式灵活地进 行事务的管理
,提高开发效率和质量。
Spring
框架不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何
Java
应用都可 以从 Spring
中受益。
Spring
框架还是一个超级粘合平台,除了自己提供功能外,还提供粘合其他技术 和框架的能力。
1.3 Spring的优势
1.4 Spring的体系结构
Spring
为我们提供了一站式解决方案,但
Spring
是模块化的,允许咱们挑选和选择适用于项目的模块, 不需要把剩余部分也引入。 Spring 框架提供约
20
个模块,可以根据应用程序的要求来选择。
?1.4.1 核心容器
核心容器由
Spring-core
,
Spring-beans
,
Spring-context
,
Spring-context-support
和
Spring-
expression
(
SpEL
,
Spring
表达式语言,
Spring Expression Language
)等模块组成
?它们的完整依赖关系如下图所示: |
|
属性
|
说明
|
|
class
|
指定
bean
对应类的全路径
|
|
name
|
name
是
bean
对应对象的一个标识
|
|
scope
|
执行
bean
对象创建模式和生命周期
,scope="singleton"
和
scope="prototype
|
|
id
|
id
是
bean
对象的唯一标识
,
不能添加特别字符
|
|
lazy-init
|
是否延时加载 默认值
:false
。
true
延迟加载对象
,
当对象被调用的时候才会加载,测试
的时候,通过
getbean()
方法获得对象。
lazy-init="false"
默认值,不延迟,无论对象
是否被使用,都会立即创建对象
,
测试时只需要加载配置文件即可。注意
:
测试的时候只
留下
id,class
属性
|
|
init-method
|
只需要加载配置文件即可对象初始化方法
|
|
destroy-method
|
hod 对象销毁方法
|
@Test
public void test02(){
String springConfig="application.xml";
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext(springConfig);
Team team1 = (Team) applicationContext.getBean("team1");
Team team11 = (Team) applicationContext.getBean("team1");
System.out.println(team1);
System.out.println(team11);
Team team2 = (Team) applicationContext.getBean("team2"); T
Team team22 = (Team) applicationContext.getBean("team2");
System.out.println(team2);
System.out.println(team22);
applicationContext.close();
//关闭容器
}
2.3.1 使用默认的构造方法
2.3.2 使用带参数的构造方法
2.3.3 使用工厂类
public Team(Integer id, String name, String location) {
this.id = id; this.name = name;
this.location = location;
System.out.println("Team - 带参数的构造方法 id="+id+",name="+name+",location="+location);
}
package com.kbb.pojo;
public class MyFactory {
/*** 实例方法 * @return */
public Team instanceFun(){
System.out.println("MyFactory------instanceFun");
return new Team(1003,"湖人","洛杉矶"); }
/*** 静态方法 * @return */
public static Team staticFun(){
System.out.println("MyFactory------staticFun");
return new Team(1004,"小牛","达拉斯");
}
public static void main(String[] args) {
Team team1 = MyFactory.staticFun(); MyFactory factory=new MyFactory(); Team team = factory.instanceFun();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
mlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--spring容器创建对象的方式:
1、通过默认构造方法
2、通过带参数的构造方法
3、通过工厂方法:实例方法,静态方法
-->
<!--1、通过默认构造方法-->
<bean id="team1" class="com.kbb.pojo.Team"></bean>
<!-- 2、通过带参数的构造方法-->
<bean id="team2" class="com.kbb.pojo.Team">
<!--name:表示参数的名称-->
<constructor-arg name="id" value="1001"/>
<constructor-arg name="name" value="勇士"/>
<constructor-arg name="location" value="金州"/>
</bean>
<bean id="team3" class="com.kbb.pojo.Team">
<!--index:表示参数的下标索引-->
<constructor-arg index="0" value="1002"/>
<constructor-arg index="1" value="热火"/>
<constructor-arg index="2" value="迈阿密"/>
</bean>
<!--3、通过工厂方法:
3.1 静态方法 Team team1 = MyFactory.staticFun();-->
<bean id="staticTeam" class="com.kbb.pojo.MyFactory" factory- method="staticFun"> </bean>
<!--3、通过工厂方法:
3.2 实例方法
MyFactory factory=new MyFactory();
Team team = factory.instanceFun();-->
<bean id="factory" class="com.kbb.pojo.MyFactory"></bean>
<bean id="instanceTeam" factory-bean="factory" factory-method="instanceFun"></bean>
</beans>
package com.lyl.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CreateTypeTest {
@Test public void test01(){
ApplicationContext ac=new ClassPathXmlApplicationContext("createType.xml");
}
}
//创建TeamDao.java
package com.kkb.dao;
public class TeamDao {
public void add(){
System.out.println("TeamDao---- add----");
}
}
//创建TeamService.java
package com.kkb.service;
import com.kkb.dao.TeamDao;
public class TeamService {
private TeamDao teamDao;//=new TeamDao();
public void add(){
teamDao.add();
System.out.println("TeamService----add----");
}
public TeamService() { }
public TeamService(TeamDao teamDao) {
this.teamDao = teamDao;
}
public TeamDao getTeamDao() {
return teamDao;
}
public void setTeamDao(TeamDao teamDao) {
this.teamDao = teamDao;
}
}
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="teamDao" class="com.lyl.dao.TeamDao"></bean>
<!-- <bean id="teamDao1" class="com.kkb.dao.TeamDao"></bean>-->
<bean id="teamService" class="com.lyl.service.TeamService">
<!--使用set方法注入属性值-->
<property name="teamDao" ref="teamDao"></property>
</bean>
<bean id="teamService2" class="com.lyl.service.TeamService">
<!--使用构造方法注入属性值-->
<constructor-arg name="teamDao" ref="teamDao"></constructor-arg>
</bean>
<!--按名称自动注入:查找容器中id名与属性名一致的对象进行注入-->
<bean id="teamService3" class="com.kkb.service.TeamService" autowire="byName"></bean>
<!--按类型自动注入:查找容器中类型与属性类型相同或者符合is-a关系的对象进行注入,但是要求类 型相同的对象唯一,否则抛出异常:不知道用哪一个匹配-->
<bean id="teamService4" class="com.kkb.service.TeamService" autowire="byType"></bean>
</beans>
package com.lyl.test;
import com.lyl.dao.TeamDao;
import com.lyl.service.TeamService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test02 {
@Test
public void test02() {
ApplicationContext ac = new ClassPathXmlApplicationContext("DI.xml");
TeamService teamService = (TeamService) ac.getBean("teamService");
teamService.add();
TeamService teamService2 = (TeamService) ac.getBean("teamService2");
teamService2.add();
TeamService teamService3 = (TeamService) ac.getBean("teamService3");
teamService3.add();
TeamService teamService4 = (TeamService) ac.getBean("teamService4");
teamService4.add();
}
@Test
public void test01() {
TeamDao teamDao = new TeamDao();
TeamService teamService = new TeamService();
teamService.setTeamDao(teamDao);
teamService.add();
}
}

?
?

<!--多个包的扫描: 方式2 : base-package中直接声明要扫描的多个包 ,多个值用逗号,分号或者空格 分割,但是空格不推荐-->
<context:component-scan base- package="com.lyl.dao,com.lyl.service,com.lyl.controller"></context:component- scan>
<!--多个包的扫描: 方式3: base-package中直接声明要扫描的多个包的父包-->
<context:component-scan base-package="com.lyl"></context:component-scan>



package com.lyl.service;
public class TeamService {
public void add() {
try {
System.out.println("开始事务");
System.out.println("TeamService---- add----");// 核心业务
System.out.println("提交事务");
} catch (Exception e) {
e.printStackTrace();
System.out.println("回滚事务");
}
}
}
package com.kkb.service;
public class TeamService {
public void add(){
System.out.println("TeamService---- add----");// 核心业务
}
}
public static void main(String[] args) {
TeamService ser=new ProxyTeamService();
ser.add();
}
package com.lyl.staticproxy;import com.kkb.service.TeamService;
/*** 基于类的静态代理: * 要求继承被代理的类 * 弊端:每次只能代理一个类 */
public class ProxyTeamService extends TeamService {
public void add() {
try {
System.out.println("开始事务");
super.add();//核心业务就是由被代理对象完成 ;其他服务功能由代理类完成
System.out.println("提交事务");
} catch (Exception e) {
System.out.println("回滚事务");
}
}
}
package com.lyl.service;
/**
* 接口定义核心方法
*/
public interface IService {
void add();
}
package com.lyl.service;
public class TeamService implements IService{
@Override
public void add(){
System.out.println("TeamService---- add----");// 核心业务
}
}
package com.lyl.service;
public class UserService implements IService{
@Override
public void add() {
System.out.println("UserService---- add-----");
}
}
package com.kkb.staticproxy;
import com.kkb.service.IService;
/**
* 基于接口的静态代理:
* 代理类和被代理类实现同一个接口
*/
public class ProxyTranService implements IService {
private IService service;//被代理的对象
public ProxyTranService(IService service) {
this.service = service;
}
@Override
public void add() {
try {
System.out.println("开始事务");
service.add();//核心业务就是由被代理对象完成 ;其他服务功能由代理类完成
System.out.println("提交事务");
}catch (Exception e){
System.out.println("回滚事务");
}
}
}
package com.kkb.staticproxy;
import com.kkb.service.IService;
public class ProxyLogService implements IService {
private IService service;//被代理对象
public ProxyLogService(IService service) {
this.service = service;
}
@Override
public void add() {
try {
System.out.println("开始日志");
service.add();//核心业务就是由被代理对象完成 ;其他服务功能由代理类完成
System.out.println("结束日志");
}catch (Exception e){
System.out.println("异常日志");
}
}
}
public static void main(String[] args) {
TeamService teamService=new TeamService();//被代理对象
UserService userService=new UserService();//被代理对象
ProxyTranService tranService=new ProxyTranService(userService);//事务代理对象--一级代理
//tranService.add();//代理对象干活
ProxyLogService logService=new ProxyLogService(tranService);//日志的代理对象--二级代理
logService.add();
}
package com.lyl.aop;
/**
* 切面:服务代码,切入到核心代码中,切入到哪里,给了四个位置
*/
public interface AOP {
void before();
void after();
void exception();
void myFinally();
}
package com.lyl.aop;
public class TranAOP implements AOP {
@Override
public void before() {
System.out.println("事务----before");
}
@Override
public void after() {
System.out.println("事务----after");
}
@Override
public void exception() {
System.out.println("事务----exception");
}
@Override
public void myFinally() {
System.out.println("事务----myFinally");
}
}
package com.lyl.aop;
public class LogAop implements AOP{
@Override
public void before() {
System.out.println("日志----before");
}
@Override
public void after() {
System.out.println("日志----after");
}
@Override
public void exception() {
System.out.println("日志----exception");
}
@Override
public void myFinally() {
System.out.println("日志----myFinally");
}
}
package com.kkb.staticproxy;
import com.kkb.aop.AOP;
import com.kkb.service.IService;
public class ProxyAOPService implements IService {
private IService service;//被代理对象
private AOP aop;//要加入切面
public ProxyAOPService(IService service, AOP aop) {
this.service = service;
this.aop = aop;
}
@Override
public void add() {
try {
aop.before();
service.add();//被代理对象干活
aop.after();
}catch (Exception e){
aop.exception();
}finally {
aop.myFinally();
}
}
}
@Testpublic
void test02() {
IService teamService = new TeamService();//被代理对象--核心内容
AOP logAop = new LogAop();//切面-服务内容
AOP tranAop = new TranAOP();
IService service = new ProxyAOPService(teamService, logAop); //代理对象--一级 代理
IService service2 = new ProxyAOPService(service, tranAop);//代理对象--二级代理
service2.add();
}
?3.4.1.1 直接编写测试类
/*newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandlerh)
ClassLoader :类加载器,因为动态代理类,借助别人的类加载器。一般使用被代理对象的类加载器。
Class<?>[] interfaces:接口类对象的集合,针对接口的代理,针对哪个接口做代理,一般使用的就是被
代理对象的接口。
InvocationHandler:句柄,回调函数,编写代理的规则代码
public Object invoke(Object arg0, Method arg1, Object[] arg2)
Object arg0:代理对象
Method arg1:被代理的方法
Object[] arg2:被代理方法被执行的时候的参数的数组
*/
package com.lyl.dynamicproxy;
import com.lyl.service.IService;
import com.lyl.service.TeamService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyJDKProxy {
public static void main(String[] args) {
//目标对象--被代理对象
TeamService teamService=new TeamService();
//返回代理对象 调用JDK中Proxy类中的静态方法newProxyInstance获取动态代理类的实例
IService proxyService= (IService) Proxy.newProxyInstance(
teamService.getClass().getClassLoader(),
teamService.getClass().getInterfaces(),
new InvocationHandler() {//回调函数 编写代理规则
@Override
public Object invoke(Object proxy, Method method, Object[]
args) throws Throwable {
try {
System.out.println("开始事务");
Object invoke = method.invoke(teamService, args);//核
心业务
System.out.println("提交事务");
return invoke;
}catch (Exception e){
System.out.println("回滚事务");
e.printStackTrace();
throw e;
}finally {
System.out.println("finally---------");
}
}
}
);
//代理对象干活
proxyService.add();
System.out.println(teamService.getClass());
System.out.println(proxyService.getClass()+"--------");
}
}
package com.kkb.dynamicproxy;
import com.kkb.aop.AOP;
import com.kkb.service.IService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyHandler implements InvocationHandler {
private IService service;//目标对象
private AOP aop;//切面
public ProxyHandler(IService service, AOP aop) {
this.service = service;
this.aop = aop;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
try {
aop.before();
Object invoke = method.invoke(service, args);//核心业务
aop.after();
return invoke;
}catch (Exception e){
aop.exception();
e.printStackTrace();
throw e;
}finally {
aop.myFinally();
}
}
}
public static void main2(String[] args) {
//目标对象--被代理对象
TeamService teamService=new TeamService();
//切面
AOP tranAop=new TranAOP();
//返回代理对象 基于JDK的动态代理
IService proxyService= (IService) Proxy.newProxyInstance(
teamService.getClass().getClassLoader(),
teamService.getClass().getInterfaces(),
new ProxyHandler(teamService,tranAop)
);
//代理对象干活
proxyService.add();
System.out.println(teamService.getClass());
System.out.println(proxyService.getClass()+"------");
}
package com.kkb.dynamicproxy;
import com.lyl.aop.AOP;
import com.lyl.service.IService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
private IService service;//目标对象
private AOP aop;//切面
public ProxyFactory(IService service, AOP aop) {
this.service = service;
this.aop = aop;
}
/**
* 获取动态代理的示例
* @return
*/
public Object getProxyInstance() {
return Proxy.newProxyInstance(
service.getClass().getClassLoader(),
service.getClass().getInterfaces(),
new InvocationHandler() {//回调函数 编写代理规则
@Override
public Object invoke(Object proxy, Method method, Object[]
args) throws Throwable {
try {
aop.before();
Object invoke = method.invoke(service, args);//核心业
务
aop.after();
return invoke;
}catch (Exception e){
aop.exception();
e.printStackTrace();
throw e;
}finally {
aop.myFinally();
}
}
}
);
}
}
public static void main(String[] args) {
//目标对象--被代理对象
TeamService teamService=new TeamService();
//切面
AOP tranAop=new TranAOP();
AOP logAop=new LogAop();
//获取代理对象
IService service= (IService) new
ProxyFactory(teamService,tranAop).getProxyInstance();
IService service1= (IService) new
ProxyFactory(service,logAop).getProxyInstance();
service1.add();//核心业务+服务代码混合在一起的完整的业务方法
}
package com.lyl.cglibproxy;
public class NBAService {
public int add(String name,int id){
System.out.println("NBAService---- add----");
return id;
}
}
public static void main(String[] args) {
//目标对象:没有接口
NBAService nbaService=new NBAService();
//创建代理对象:选择cglib动态代理
NBAService proxyService= (NBAService)
Enhancer.create(nbaService.getClass(),
new MethodInterceptor() {//回调函数编写代理规则
@Override
public Object intercept(Object o, Method method, Object[] objects,
MethodProxy methodProxy) throws Throwable {
try {
System.out.println("开始事务");
Object invoke = methodProxy.invokeSuper(o, objects);//核心
System.out.println("提交事务");
return invoke;
}catch (Exception e){
System.out.println("事务回滚");
throw e;
}finally {
System.out.println("finally------------");
}
}
});
//代理对象干活
int res=proxyService.add("huren",1001);
System.out.println(res);
}
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
| 符号 | 意义 |
| * |
0-
多个任意字符
|
| .. |
用在方法参数中,表示任意个参数;用在包名后,表示当前及其子包路径
|
| + |
用在类名后,表示当前及其子类;用在接口后,表示当前接口及其实现类
|
<dependencies>
<!--spring 核心依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.13.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.13.RELEASE</version>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!--编译插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring- beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--在beans标签中 引入AOP和context约束-->
</beans>
public interface IService {
void add(int id,String name);
boolean update(int num);
}
package com.kkb.service;
import org.springframework.stereotype.Service;
/**
* 核心业务类
*/
@Service
public class TeamService implements IService{
@Override
public void add(int id, String name) {
System.out.println("TeamService---- add----");
}
@Override
public boolean update(int num) {
System.out.println("TeamService---- update----");
//int res=10/0;
if(num>666){
return true;
}
return false;
}
}
package com.kkb.service;
import org.springframework.stereotype.Service;
/**
* 核心业务类
*/
@Service("nbaService")
public class NBAService implements IService{
@Override
public void add(int id, String name) {
System.out.println("NBAService---- add----");
}
@Override
public boolean update(int num) {
System.out.println("NBAService---- update----");
//int res=10/0;
if(num>666){
return true;
}
return false;
}
}
4.定义切面类
package com.lyl.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* 切面类
*/
//@Component 切面对象的创建权限依然交给spring容器
//@Aspect aspectj 框架的注解 标识当前类是一个切面类
public class MyAspect{
/**
* 当较多的通知增强方法使用相同的 execution 切入点表达式时,编写、维护均较为麻烦。
* AspectJ 提供了@Pointcut 注解,用于定义 execution 切入点表达式。
* 其用法是,将@Pointcut 注解在一个方法之上,以后所有的 execution 的 value 属性值均
* 可使用该方法名作为切入点。代表的就是@Pointcut 定义的切入点。
* 这个使用@Pointcut 注解方法一般使用 private 的标识方法,即没有实际作用的方法。
*/
@Pointcut("execution(* com.kkb.service..*.*(..))")
private void pointCut(){
}
@Pointcut("execution(* com.kkb.service..*.add*(..))")
private void pointCut2(){
}
/**
* 声明前置通知
* @param jp
*/
@Before("pointCut()")
public void before(JoinPoint jp){
System.out.println("前置通知:在目标方法执行之前被调用的通知");
String name = jp.getSignature().getName();
System.out.println("拦截的方法名称:"+name);
Object[] args = jp.getArgs();
System.out.println("方法的参数格式:"+args.length);
System.out.println("方法参数列表:");
for (Object arg : args) {
System.out.println("\t"+arg);
}
}
/**
* AfterReturning 注解声明后置通知
* value: 表示切入点表达式
* returning 属性表示 返回的结果,如果需要的话可以在后置通知的方法中修改结果
*/
@AfterReturning(value = "pointCut2()",returning = "result")
public Object afterReturn(Object result){
if(result!=null){
boolean res=(boolean)result;
if(res){
result=false;
}
}
System.out.println("后置通知:在目标方法执行之后被调用的通知,result="+result);
return result;
}
/**
* Around 注解声明环绕通知
* ProceedingJoinPoint 中的proceed方法表示目标方法被执行
*/
@Around(value = "pointCut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕方法---目标方法的执行之前");
Object proceed = pjp.proceed();
System.out.println("环绕方法---目标方法的执行之后");
return proceed;
}
/**
* AfterThrowing 注解声明异常通知方法
* value: 表示切入点表达式
* returning 属性表示 返回的结果,如果需要的话可以在后置通知的方法中修改结果
*/
@AfterThrowing(value = "pointCut()",throwing = "ex")
public void exception(JoinPoint jp,Throwable ex){
//一般会把异常发生的时间、位置、原有都记录下来
System.out.println("异常通知:在目标方法执行出现异常的时候才会别调用的通知,否则不
执行");
System.out.println(jp.getSignature()+"方法出现异常,异常信息
是:"+ex.getMessage());
}
/**
* After 注解声明为最终通知
*/
@After( "pointCut()")
public void myFinally(){
System.out.println("最终通知:无论是否出现异常都是最后被调用的通知");
}
}
?
<!--包扫描-->
<context:component-scan base-package="com.kkb.service,com.kkb.aop"/>
<!--开启注解AOP的使用-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!--aop:aspectj-autoproxy的底层是由 AnnotationAwareAspectJAutoProxyCreator 实现的,
是基于 AspectJ 的注解适配自动代理生成器。
其工作原理是,aop:aspectj-autoproxy通过扫描找到@Aspect 定义的切面类,再由切面类根据切入点找 到目标类的目标方法,再由通知类型找到切入的时间点。-->
package com.kkb.test;
import com.lyl.service.NBAService;
import com.lyl.service.TeamService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test01 {
@Test
public void test01(){
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
TeamService teamService = (TeamService) ac.getBean("teamService");
teamService.add(1001,"湖人队");
System.out.println("--------------------------");
boolean update = teamService.up
System.out.println("update 结果="+update);
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
NBAService nbaService = (NBAService) ac.getBean("nbaService");
nbaService.add(1002,"热火");
System.out.println("--------------------------");
boolean update2 = teamService.update(888);
System.out.println("update 结果="+update2);
}
}
<aop:config>
<!--声明切入点的表达式,可以声明多个-->
<aop:pointcut id="pt1" expression="execution(* com.kkb.service..*.add*
(..))"/>
<aop:pointcut id="pt2" expression="execution(*
com.kkb.service..*.update*(..))"/>
<aop:pointcut id="pt3" expression="execution(* com.kkb.service..*.del*
(..))"/>
<aop:pointcut id="pt4" expression="execution(*
com.kkb.service..*.insert*(..))"/>
<aop:aspect ref="myAOP">
<aop:before method="before" pointcut="execution(*
com.kkb.service..*.*(..))"></aop:before>
<aop:after-returning method="afterReturn" pointcut-ref="pt2"
returning="result"></aop:after-returning>
<aop:after-throwing method="exception" pointcut-ref="pt1"
throwing="ex"></aop:after-throwing>
<aop:after method="myFinally" pointcut-ref="pt1"></aop:after>
<aop:around method="around" pointcut-ref="pt2"></aop:around>
</aop:aspect>
package com.lyl.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* 切面类
*/
@Component //切面对象的创建权限依然交给spring容器
@Aspect //aspectj 框架的注解 标识当前类是一个切面类
public class MyAOP {
public void before(JoinPoint jp){
System.out.println("AOP前置通知:在目标方法执行之前被调用的通知");
}
public void afterReturn(Object result){
System.out.println("AOP后置通知:在目标方法执行之后被调用的通
知,result="+result);
}
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("AOP环绕方法---目标方法的执行之前");
Object proceed = pjp.proceed();
System.out.println("AOP环绕方法---目标方法的执行之后");
return proceed;
}
public void exception(JoinPoint jp,Throwable ex){
//一般会把异常发生的时间、位置、原有都记录下来
System.out.println("AOP异常通知:在目标方法执行出现异常的时候才会别调用的通知,否则
不执行");
System.out.println(jp.getSignature()+"方法出现异常,异常信息
是:"+ex.getMessage());
}
public void myFinally(){
System.out.println("AOP最终通知:无论是否出现异常都是最后被调用的通知");
}
}
<dependencies>
<!--spring 核心依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.13.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.13.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!--编译插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
package com.lyl.test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import java.beans.PropertyVetoException;
public class Test01 {
@Test
public void test01() throws PropertyVetoException {
//创建数据源
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://192.168.58.128:3306/springJDBC? serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false");
dataSource.setUser("root");
dataSource.setPassword("root"); //使用JDBCTemplete
JdbcTemplate template = new JdbcTemplate(dataSource);
String sql = "insert into team(tname,location) value (?,?)";
int update = template.update(sql, "勇士", "金州");
System.out.println("插入数据的结果:" + update);
}
}
package com.kkb.dao;
import com.lyl.pojo.Team;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
public class TeamDao extends JdbcDaoSupport {
public int getCount() {
String sql = "select count(tid) from team";
return this.getJdbcTemplate().queryForObject(sql, Integer.class);
}
public Map<String, Object> getMany() {
String sql = "select max(tid),min(tid) from team";
return this.getJdbcTemplate().queryForMap(sql);
}
/**
* 自己封装一个处理结果的方法
*
* @param resultSet
* @return
* @throws SQLException
*/
public Team handlResult(ResultSet resultSet) throws SQLException {
Team team = new Team();
team.setId(resultSet.getInt("tid"));
team.setName(resultSet.getString("tname"));
team.setLocation(resultSet.getString("location"));
return team;
}
public List<Team> findAll() {
String sql = "select * from team";
return this.getJdbcTemplate().query(sql, new RowMapper<Team>() {
@Override
public Team mapRow(ResultSet resultSet, int i) throws SQLException {
/* Team team=new Team();
team.setId(resultSet.getInt("tid"));
team.setName(resultSet.getString("tname"));
team.setLocation(resultSet.getString("location"));*/
return handlResult(resultSet);
}
});
}
public Team findById(int id) {
String sql = "select * from team where tid=?";
return this.getJdbcTemplate().queryForObject(sql, new Object[]{id}, new
RowMapper<Team>() {
@Override
public Team mapRow(ResultSet resultSet, int i) throws SQLException {
/* Team team=new Team();
team.setId(resultSet.getInt("tid"));
team.setName(resultSet.getString("tname"));
team.setLocation(resultSet.getString("location"));*/
return handlResult(resultSet);
}
});
}
public int insert(Team team) {
//使用JDBCTemplete
// JdbcTemplate template=new JdbcTemplate(dataSource);
String sql = "insert into team(tname,location) value (?,?)";
return
this.getJdbcTemplate().update(sql, team.getName(), team.getLocation());
}
public int update(Team team) {
//使用JDBCTemplete
// JdbcTemplate template=new JdbcTemplate(dataSource);
String sql = "update team set tname=? ,location=? where tid=?";
return
this.getJdbcTemplate().update(sql, team.getName(), team.getLocation(), team.getId(
));
}
public int del(int id) {
//使用JDBCTemplete
// JdbcTemplate template=new JdbcTemplate(dataSource);
String sql = "delete from team where tid=?";
return this.getJdbcTemplate().update(sql, id);
}
}
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--创建数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver">
</property>
<property name="jdbcUrl"
value="jdbc:mysql://192.168.58.128:3306/springJDBC?
serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=fal
se"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!--创建JdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--需要注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="teamDao" class="com.kkb.dao.TeamDao">
<!--需要JdbcTemplate-->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
</beans>
测试:
package com.lyl.test;
import com.lyl.dao.TeamDao;
import com.lyl.pojo.Team;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import java.beans.PropertyVetoException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Test01 {
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
@Test
public void testGet() {
TeamDao dao = (TeamDao) ac.getBean("teamDao");
int count = dao.getCount();
System.out.println("查询的总行数:" + count);
Map<String, Object> many = dao.getMany();
Set<Map.Entry<String, Object>> entries = many.entrySet();
for (Map.Entry<String, Object> entry : entries) {
System.out.println(entry.getKey() + "----" + entry.getValue());
}
}
@Test
public void testFindAll() {
TeamDao dao = (TeamDao) ac.getBean("teamDao");
List<Team> all = dao.findAll();
for (Team team : all) {
System.out.println(team);
}
}
@Test
public void testFindById() {
TeamDao dao = (TeamDao) ac.getBean("teamDao");
Team t = dao.findById(2);
System.out.println(t);
}
@Test
public void testDel() {
TeamDao dao = (TeamDao) ac.getBean("teamDao");
int res = dao.del(6);
System.out.println("删除数据的结果:" + res);
}
@Test
public void testUpdate() {
ApplicationContext ac = new
ClassPathXmlApplicationContext("application.xml");
TeamDao dao = (TeamDao) ac.getBean("teamDao");
Team team = new Team();
team.setName("小牛");
team.setLocation("达拉斯");
team.setId(4);
int res = dao.update(team);
System.out.println("更新数据的结果:" + res);
}
@Test
public void test() {
ApplicationContext ac = new
ClassPathXmlApplicationContext("application.xml");
TeamDao dao = (TeamDao) ac.getBean("teamDao");
Team team = new Team();
team.setName("快船1");
team.setLocation("洛杉矶1");
int res = dao.insert(team);
System.out.println("插入数据的结果:" + res);
}
@Test
public void test01() throws PropertyVetoException {
//创建数据源
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://192.168.58.128:3306/springJDBC?
serverTimezone = UTC & characterEncoding = utf8 & useUnicode = true & useSSL = false");
dataSource.setUser("root");
dataSource.setPassword("root");
//使用JDBCTemplete
JdbcTemplate template = new JdbcTemplate(dataSource);
String sql = "insert into team(tname,location) value (?,?)";
int update = template.update(sql, "勇士", "金州");
System.out.println("插入数据的结果:" + update);
}
}
?
?
事务传播行为常量都是以 PROPAGATION_ 开头,形如 PROPAGATION_XXX。
package com.lyl.service;
import com.lyl.dao.TeamDao;
import com.lyl.pojo.Team;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
public class TeamService {
@Autowired
private TeamDao teamDao;
/**
* @Transactional 属性 说明:
* readOnly:是否只读
* <p>
* rollbackFor={Exception.class}: 遇到什么异常会回滚
* <p>
* propagation事务的传播:
* Propagation.REQUIRED:当前没有事务的时候,就会创建一个新的事务;如果当前有事务,就直
* 接加入该事务,比较常用的设置
* Propagation.SUPPORTS:支持当前事务,如果当前有事务,就直接加入该事务;当前没有事务的
* 时候,就以非事务方式执行
* Propagation.MANDATORY:支持当前事务,如果当前有事务,就直接加入该事务;当前没有事务的
* 时候,就抛出异常
* Propagation.REQUIRES_NEW:创建新事务,无论当前是否有事务都会创建新的
* <p>
* isolation=Isolation.DEFAULT:事务的隔离级别:默认是数据库的隔离级别
*/
@Transactional(propagation = Propagation.REQUIRED, rollbackFor =
{Exception.class})
public int insert(Team team) {
int num1 = teamDao.insert(team);
System.out.println("第一条执行结果:num1=" + num1);
System.out.println(10 / 0);
int num2 = teamDao.insert(team);
System.out.println("第二条执行结果:num2=" + num2);
return num2 + num1;
}
}
@Test
public void test01(){
ApplicationContext ac=new ClassPathXmlApplicationContext("application.xml");
TeamService teamService = (TeamService) ac.getBean("teamService");
int num=teamService.insert(new Team("凯尔特人","波士顿"));
System.out.println(num);
}
<!--配置文件中添加context约束-->
<context:component-scan base-package="com.lyl"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> <tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice> <aop:config>
<aop:pointcut id="pt" expression="execution(* com.kkb.service..*.* (..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>
|
|
|
|
| 上一篇文章 下一篇文章 查看所有文章 |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| 360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年11日历 | -2025/11/29 1:53:29- |
|
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |