您的位置 首页 > 雕刻工具

spring(Spring详解)

各位老铁们,大家好,今天由我来为大家分享spring,以及Spring详解的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!

官网:https://docs.spring.io/spring-framework/docs/current/reference/html/overview.html#overview

官方下载地址:https://repo.spring.io/ui/native/release/org/springframework/spring

GitHub:https://github.com/spring-projects/spring-framework

<!--https://mvnrepository.com/artifact/org.springframework/spring-webmvc-->\n<dependency>\n<groupId>org.springframework</groupId>\n<artifactId>spring-webmvc</artifactId>\n<version>5.3.17</version>\n</dependency>\n<!--https://mvnrepository.com/artifact/org.springframework/spring-jdbc-->\n<dependency>\n<groupId>org.springframework</groupId>\n<artifactId>spring-jdbc</artifactId>\n<version>5.3.17</version>\n</dependency>\n1.2、优点Spring是一个开源的免费的框架(容器)!Spring是一个轻量级的、非入侵式的框架!控制反转(IOC),面向切面编程(AOP)!支持事务的处理,对框架整合的支持!

总结一句话:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!

在Spring的官网有这个介绍:现代化的Java开发!说白就是基于Spring开发!

因为现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring及SpringMVC!承上启下的作用!

弊端:发展了太久之后,违背了原来的理念!配置十分繁琐,人称:“配置地狱!”

在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改源代码!如果程序代码量十分大,修改一次的成本代价十分昂贵!

我们使用一个Set接口实现。已经发生了革命性的变化!

privateUserDaouserDao;\n\n//利用set进行动态实现值的注入!\npublicvoidsetUserDao(UserDaouserDao){\nthis.userDao=userDao;\n}\n=========================================\npublicstaticvoidmain(String[]args){\n\n//用户实际调用的是业务层,dao层它们不需要接触!\nUserServiceuserService=newUserServiceImpl();\n((UserServiceImpl)userService).setUserDao(newUserDaoMysqlImpl());\nuserService.getUser();\n}\n之前,程序是主动创建对象!控制权在程序员手上!使用了set注入后,程序不再具有主动性,而是变成了被动的接收对象!

这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建了。系统的耦合性大大降低~。可以更加专注在业务的实现上!这是IOC的原型!

控制反转IoC(InversionofControl),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

采用XML方式配置Bean的时候,Bean的定义信息是和现实分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(DependencyInjection,DI)。

注:spring需要导入commons-logging进行日志记录,我们利用maven,它会自动下载对应的依赖项

<!--https://mvnrepository.com/artifact/org.springframework/spring-webmvc-->\n<dependency>\n<groupId>org.springframework</groupId>\n<artifactId>spring-webmvc</artifactId>\n<version>5.3.17</version>\n</dependency>\n

编写代码

依赖注入:就是利用set方法来进行注入的。

IOC是一种编程思想,由主动的编程编程被动的接收

可以通过newClassPathXmlApplicationContext去浏览一下底层源码。

总结:在配置文件加载的时候,容器中管理的对象就已经初始化了

<!--别名发,如果添加了别名,我们也可以使用别名获取到这个对象-->\n<aliasname="user"alias="userNew"/>\n5.2、Bean的配置

<!--\nid:bean的唯一标识符,也就是相当于我们学的对象名\nclass:bean对象所对应的全限定名:包名+类型\nname:也是别名,而且name可以同时取多个别名\n-->\n<beanid="userT"class="com.kuang.pojo.UserT"name="user2,u2u3;u4">\n<propertyname="name"value="西部开源"/>\n</bean>\n5.3、import

这个import,一般用于团队开发使用,它可以将多个配置文件,导入合并为一个

假设,现在项目中有多个人开发,这三个人负责不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import,将所有人的beans.xml合并为一个总的!

使用的时候,直接使用总的配置就可以了

我们可以使用p命名空间和c命名空间进行注入

<?xmlversion="1.0"encoding="UTF-8"?>\n<beansxmlns="http://www.springframework.org/schema/beans"\nxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\nxmlns:p="http://www.springframework.org/schema/p"\nxmlns:c="http://www.springframework.org/schema/c"\nxsi:schemaLocation="http://www.springframework.org/schema/beans\nhttps://www.springframework.org/schema/beans/spring-beans.xsd">\n\n<!--p命名空间注入,可以直接注入属性的值:property-->\n<beanid="user"class="com.kuang.pojo.User"p:name="qinjiang"p:age="18"/>\n\n<!--c命名空间注入,通过构造器注入:constructor-args-->\n<beanid="user2"class="com.kuang.pojo.User"c:age="18"c:name="kuangshen"/>\n\n</beans>\n

测试:

@Test\npublicvoidtest2(){\nApplicationContextcontext=newClassPathXmlApplicationContext("userbean.xml");\nUseruser=context.getBean("user2",User.class);\nSystem.out.println(user);\n}\n

注意点:p命名和c命名空间不能直接使用,需要导入xml约束!

xmlns:p="http://www.springframework.org/schema/p"\nxmlns:c="http://www.springframework.org/schema/c"\n6.4、bean的作用域单例模式(Spring默认机制)<beanid="user2"class="com.kuang.pojo.User"c:age="18"c:name="kuangshen"scope="singleton"/>原型模式:每次从容器中get的时候,都会产生一个新对象!<beanid="accountService"class="com.something.DefaultAccountService"scope="prototype"/>其余的request、session、application这些个只能在web开发中使用到!7、Bean的自动装配自动装配是Spring满足bean依赖的一种方式!Spring会在上下文中自动寻找,并自动给bean装配属性!

在Spring中有三种装配的方式

<!--\nbyName:会自动在容器上下文查找,和自己对象set方法后面的值对应的beanid!\n-->\n<beanid="people"class="com.kuang.pojo.People"autowire="byName">\n<propertyname="name"value="kuangshen"/>\n</bean>\n7.3、ByType自动装配

<beanclass="com.kuang.pojo.Cat"/>\n<beanclass="com.kuang.pojo.Dog"/>\n\n<!--\nbyName:会自动在容器上下文查找,和自己对象set方法后面的值对应的beanid!\nbyType:会自动在容器上下文查找,和自己对象属性类型相同的bean!\n-->\n<beanid="people"class="com.kuang.pojo.People"autowire="byType">\n<propertyname="name"value="kuangshen"/>\n</bean>\n

小结:

jdk1.5支持的注解,Spring2.5就支持注解了!

Theintroductionofannotation-basedconfigurationraisedthequestionofwhetherthisapproachis“better”thanXML.

直接在属性上使用即可!也可以在set方法上使用!

使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在IOC(Spring)容器中存在,通过byType,再通过byname查找!

@Nullable字段标记了这个注解,说明这个字段可以为null;\n

public@interfaceAutowired{\nbooleanrequired()defaulttrue;\n}\n

测试代码

publicclassPeople{\n\nprivateStringname;\n@Autowired\nprivateDogdog;\n//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空\n@Autowired(required=false)\nprivateCatcat;\n}\n

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value="xxx")去配合@Autowired的使用,指定一个唯一的bean对象注入!

publicclassPeople{\n\nprivateStringname;\n@Autowired\n@Qualifier(value="dog222")\nprivateDogdog;\n//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空\n@Autowired\nprivateCatcat;\n}\n

@Resource注解

publicclassPeople{\n\nprivateStringname;\n@Resource(name="dog222")\nprivateDogdog;\n//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空\n@Resource\nprivateCatcat;\n}\n

小结:

在Spring4之后,要使用注解开发,必须要保证aop的包导入了

使用注解需要导入context约束,增加注解的支持!

<?xmlversion="1.0"encoding="UTF-8"?>\n<beansxmlns="http://www.springframework.org/schema/beans"\nxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\nxmlns:context="http://www.springframework.org/schema/context"\nxsi:schemaLocation="http://www.springframework.org/schema/beans\nhttps://www.springframework.org/schema/beans/spring-beans.xsd\nhttp://www.springframework.org/schema/context\nhttps://www.springframework.org/schema/context/spring-context.xsd">\n\n<context:annotation-config/>\n\n</beans>\nbean属性如何注入@ComponentpublicclassUser{publicStringname;//相当于<propertyname="name"value="kuangshen"/>@Value("kuangshen")publicvoidsetName(Stringname){this.name=name;}}衍生的注解@Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!dao【@Repository】service【@Service】controller【@Controller】这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean自动装配-@Autowired:自动装配通过类型,然后名字如果Autowired不能唯一装配上属性,则需要通过@Qualifier(value="xxx")-@Nullable字段标记了这个注解,说明这个字段可以为null;-@Resource:自动装配通过名字,然后类型-@Component:组件,放在类上,说明这个类被Spring管理了,就是bean!作用域@Component@Scope("prototype")publicclassUser{publicStringname;//相当于<propertyname="name"value="kuangshen"/>@Value("kuangshen")publicvoidsetName(Stringname){this.name=name;}}小结xml与注解:xml更加万能,适用于任何场合!维护简单方便注解不是自己的类使用不了,维护相对复杂!xml与注解最佳实践:xml用来管理bean;注解只负责完成属性的注入;我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持<!--指定要扫描的包,这个包下的注解就会生效--><context:component-scanbase-package="com.kuang"/><context:annotation-config/>9、使用Java的方式配置Spring

我们现在要完全不使用Spring的xml配置了,全权交给Java来做!

JavaConfig是Spring的一个子项目,在Spring4之后,它成为了一个核心功能!

//这里这个注解的意思,就是说明这个类被Spring接管了,注册到了容器中\n@Component\npublicclassUser{\nprivateStringname;\n\n@Override\npublicStringtoString(){\nreturn"User{"+\n"name='"+name+'\\''+\n'}';\n}\n\npublicStringgetName(){\nreturnname;\n}\n\n@Value("qinjiang")//属性注入值\npublicvoidsetName(Stringname){\nthis.name=name;\n}\n}\n

配置文件:

packagecom.kuang.config;\n\nimportcom.kuang.pojo.User;\nimportorg.springframework.context.annotation.Bean;\nimportorg.springframework.context.annotation.ComponentScan;\nimportorg.springframework.context.annotation.Configuration;\nimportorg.springframework.context.annotation.Import;\n\n//这个也会被Spring容器托管,注册到容器中,因为它本来就是一个@Component\n//@Configuration代表这是一个配置类,就和我们之前看的beans.xml是一样的\n@Configuration\n@ComponentScan("com.kuang.pojo")\n@Import(KuangConfig2.class)\npublicclassKuangConfig{\n\n//注册一个bean,就相当于我们之前写的一个bean标签\n//这个方法的名字,就相当于bean标签中的id属性\n//这个方法的返回值,就相当于bean标签中的class属性\n@Bean\npublicUseruser(){\nreturnnewUser();//就是返回要注入到bean的对象!\n}\n}\n

测试类!

publicclassMyTest{\npublicstaticvoidmain(String[]args){\n//如果完全使用了配置类方式去做,我们就只能通过AnnotationConfig上下文来获取容器,通过配置类的class对象加载!\nApplicationContextcontext=newAnnotationConfigApplicationContext(KuangConfig.class);\nUseruser=(User)context.getBean("user");\n\nSystem.out.println(user.getName());\n}\n}\n

这种纯Java的配置方式,在SpringBoot中随处可见!

为什么要学习代理模式?因为这就是SpringAOP的底层!【SpringAOP和SpringMVC】

publicinterfaceUserService{\nvoidadd();\nvoiddelete();\nvoidupdate();\nvoidquery();\n}\n==============================================\n//真实对象\npublicclassUserServiceImplimplementsUserService{\n@Override\npublicvoidadd(){\nSystem.out.println("增加了一个用户");\n}\n\n@Override\npublicvoiddelete(){\nSystem.out.println("删除了一个用户");\n}\n\n@Override\npublicvoidupdate(){\nSystem.out.println("修改了一个用户");\n}\n\n@Override\npublicvoidquery(){\nSystem.out.println("查询了一个用户");\n}\n\n//1.改动原有的业务代码,在公司中是大忌\n}\n==============================================\npublicclassUserServiceProxyimplementsUserService{\n\nprivateUserServiceImpluserserviceimpl;\n\npublicUserServiceImplgetUserserviceimpl(){\nreturnuserserviceimpl;\n}\n\npublicvoidsetUserserviceimpl(UserServiceImpluserserviceimpl){\nthis.userserviceimpl=userserviceimpl;\n}\n\n@Override\npublicvoidadd(){\nlog("add");\nuserserviceimpl.add();\n}\n\n@Override\npublicvoiddelete(){\nlog("delete");\nuserserviceimpl.delete();\n}\n\n@Override\npublicvoidupdate(){\nlog("update");\nuserserviceimpl.update();\n}\n\n@Override\npublicvoidquery(){\nlog("query");\nuserserviceimpl.query();\n}\n\n//日志方法\npublicvoidlog(Stringmsg){\nSystem.out.println("[Debug]使用了"+msg+"方法");\n}\n}\n===============================================\npublicclassClient{\n\npublicstaticvoidmain(String[]args){\nUserServiceImpluserserviceimpl=newUserServiceImpl();\nUserServiceProxyproxy=newUserServiceProxy();\n\nproxy.setUserserviceimpl(userserviceimpl);\n\nproxy.add();\n}\n}\n

聊聊AOP

需要了解两个类:Proxy:代理,InvocationHandler:调用处理程序

//租房\npublicinterfaceRent{\npublicvoidrent();\n}\n===========================================\n//房东\npublicclassHostimplementsRent{\n\n@Override\npublicvoidrent(){\nSystem.out.println("房东要出租房子!");\n}\n}\n============================================\n//等会我们会用这个类,自动生成代理类!\npublicclassProxyInvocationHandlerimplementsInvocationHandler{\n\n//被代理的接口\nprivateRentrent;\n\npublicvoidsetRent(Rentrent){\nthis.rent=rent;\n}\n\n//生成得到代理类\npublicObjectgetProxy(){\nreturnProxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);\n}\n\n//处理代理实例,并返回结果\n@Override\npublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{\n\n//动态代理的本质,就是使用反射机制实现!\nseeHouse();\nObjectresult=method.invoke(rent,args);\nfare();\nreturnresult;\n\n}\n\npublicvoidseeHouse(){\nSystem.out.println("中介带看房子");\n}\npublicvoidfare(){\nSystem.out.println("收中介费");\n}\n}\n====================================================\npublicclassClient{\npublicstaticvoidmain(String[]args){\n//真实角色\nHosthost=newHost();\n\n//代理角色:现在没有\nProxyInvocationHandlerpih=newProxyInvocationHandler();\n//通过调用程序处理角色来处理我们要调用的接口对象!\npih.setRent(host);\nRentproxy=(Rent)pih.getProxy();//这里的proxy就是动态生成的,我们并没有写!\nproxy.rent();\n}\n}\n

代码改进:

//等会我们会用这个类,自动生成代理类!\npublicclassProxyInvocationHandlerimplementsInvocationHandler{\n\n//被代理的接口\nprivateObjecttarget;\n\npublicvoidsetTarget(Objecttarget){\nthis.target=target;\n}\n\n//生成得到代理类\npublicObjectgetProxy(){\nreturnProxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);\n}\n\n//处理代理实例,并返回结果\n@Override\npublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{\n\n//动态代理的本质,就是使用反射机制实现!\nlog(method.getName());\nObjectresult=method.invoke(target,args);\nreturnresult;\n}\n\npublicvoidlog(Stringmsg){\nSystem.out.println("执行了"+msg+"方法");\n}\n}\n=============================================================\npublicclassClient{\npublicstaticvoidmain(String[]args){\n//真实角色\nUserServiceImpluserService=newUserServiceImpl();\n//代理角色,不存在\nProxyInvocationHandlerpih=newProxyInvocationHandler();\n\npih.setTarget(userService);//设置要代理的对象\n//动态生成代理类\nUserServiceproxy=(UserService)pih.getProxy();\n\nproxy.query();\n\n}\n}\n11、AOP11.1、什么是AOP

AOP(AspectOrientedProgramming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

提供声明式事务;允许用户自定义切面

SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:

即AOP在不改变原有代码的情况下,去增加新的功能。

【重点】使用AOP注入,需要导入一个依赖包!

<!--https://mvnrepository.com/artifact/org.aspectj/aspectjweaver-->\n<dependency>\n<groupId>org.aspectj</groupId>\n<artifactId>aspectjweaver</artifactId>\n<version>1.9.9</version>\n</dependency>\n

方式一:使用Spring的API接口【主要是SpringAPI接口实现】

<?xmlversion="1.0"encoding="UTF-8"?>\n<beansxmlns="http://www.springframework.org/schema/beans"\nxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\nxmlns:aop="http://www.springframework.org/schema/aop"\nxsi:schemaLocation="http://www.springframework.org/schema/beans\nhttps://www.springframework.org/schema/beans/spring-beans.xsd\nhttp://www.springframework.org/schema/aop\nhttps://www.springframework.org/schema/aop/spring-aop.xsd">\n\n<!--注册bean-->\n<beanid="userService"class="com.kuang.service.UserServiceImpl"/>\n<beanid="afterLog"class="com.kuang.log.AfterLog"/>\n<beanid="log"class="com.kuang.log.Log"/>\n\n<!--方式一:使用原生SpringAPI接口-->\n<!--配置aop:需要导入aop的约束-->\n<aop:config>\n<!--切入点:expression:表达式,execution(要执行的位置!*****)修饰词类方法名参数-->\n<aop:pointcutid="pointcut"expression="execution(*com.kuang.service.UserServiceImpl.*(..))"/>\n\n<!--执行环绕增加!-->\n<aop:advisoradvice-ref="log"pointcut-ref="pointcut"/>\n<aop:advisoradvice-ref="afterLog"pointcut-ref="pointcut"/>\n</aop:config>\n</beans>\n

publicinterfaceUserService{\n\nvoidadd();\nvoiddelete();\nvoidupdate();\nvoidselect();\n}\n============================================\npublicclassUserServiceImplimplementsUserService{\npublicvoidadd(){\nSystem.out.println("增加了一个用户");\n}\n\npublicvoiddelete(){\nSystem.out.println("删除了一个用户");\n}\n\npublicvoidupdate(){\nSystem.out.println("更新了一个用户");\n}\n\npublicvoidselect(){\nSystem.out.println("查询了一个用户");\n}\n}\n=============================================\npublicclassAfterLogimplementsAfterReturningAdvice{\n//returnValue;返回值\npublicvoidafterReturning(ObjectreturnValue,Methodmethod,Object[]args,Objecttarget)throwsThrowable{\nSystem.out.println("执行了"+method.getName()+"方法,返回结果为:"+returnValue);\n}\n}\n==============================================\npublicclassLogimplementsMethodBeforeAdvice{\n\n//method:要执行的目标对象的方法\n//object:参数\n//target:目标对象\npublicvoidbefore(Methodmethod,Object[]args,Objecttarget)throwsThrowable{\nSystem.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");\n}\n}\n==============================================\npublicclassMyTest{\npublicstaticvoidmain(String[]args){\nApplicationContextcontext=newClassPathXmlApplicationContext("applicationContext.xml");\n//动态代理代理的是接口:注意点\nUserServiceuserService=context.getBean("userService",UserService.class);\n\nuserService.add();\n}\n}\n

方式二:自定义类来实现AOP【主要是切面定义】

<?xmlversion="1.0"encoding="UTF-8"?>\n<beansxmlns="http://www.springframework.org/schema/beans"\nxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\nxmlns:aop="http://www.springframework.org/schema/aop"\nxsi:schemaLocation="http://www.springframework.org/schema/beans\nhttps://www.springframework.org/schema/beans/spring-beans.xsd\nhttp://www.springframework.org/schema/aop\nhttps://www.springframework.org/schema/aop/spring-aop.xsd">\n\n<!--注册bean-->\n<beanid="userService"class="com.kuang.service.UserServiceImpl"/>\n<beanid="afterLog"class="com.kuang.log.AfterLog"/>\n<beanid="log"class="com.kuang.log.Log"/>\n\n<!--方式一:使用原生SpringAPI接口-->\n<!--配置aop:需要导入aop的约束-->\n<!--<aop:config>-->\n<!--<!–切入点:expression:表达式,execution(要执行的位置!*****)修饰词类方法名参数–>-->\n<!--<aop:pointcutid="pointcut"expression="execution(*com.kuang.service.UserServiceImpl.*(..))"/>-->\n<!--<!–执行环绕增加!–>-->\n<!--<aop:advisoradvice-ref="log"pointcut-ref="pointcut"/>-->\n<!--<aop:advisoradvice-ref="afterLog"pointcut-ref="pointcut"/>-->\n<!--</aop:config>-->\n\n<!--方式二:自定义类-->\n<beanid="diy"class="com.kuang.diy.DiyPointCut"/>\n\n<aop:config>\n<!--自定义切面,ref要引用的类-->\n<aop:aspectref="diy">\n<!--切入点execution(返回类型包名(类名)方法名)-->\n<aop:pointcutid="point"expression="execution(*com.kuang.service.UserServiceImpl.*(..))"/>\n<!--通知-->\n<aop:beforemethod="before"pointcut-ref="point"/>\n<aop:aftermethod="after"pointcut-ref="point"/>\n</aop:aspect>\n</aop:config>\n\n</beans>\n

publicclassDiyPointCut{\n\npublicvoidbefore(){\nSystem.out.println("=========方法执行前=========");\n}\npublicvoidafter(){\nSystem.out.println("=========方法执行后=========");\n}\n}\n============================================================\npublicclassMyTest{\npublicstaticvoidmain(String[]args){\nApplicationContextcontext=newClassPathXmlApplicationContext("applicationContext.xml");\n//动态代理代理的是接口:注意点\nUserServiceuserService=context.getBean("userService",UserService.class);\n\nuserService.add();\n}\n}\n

方式三:使用注解实现!

<?xmlversion="1.0"encoding="UTF-8"?>\n<beansxmlns="http://www.springframework.org/schema/beans"\nxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\nxmlns:aop="http://www.springframework.org/schema/aop"\nxsi:schemaLocation="http://www.springframework.org/schema/beans\nhttps://www.springframework.org/schema/beans/spring-beans.xsd\nhttp://www.springframework.org/schema/aop\nhttps://www.springframework.org/schema/aop/spring-aop.xsd">\n\n<!--注册bean-->\n<beanid="userService"class="com.kuang.service.UserServiceImpl"/>\n<beanid="afterLog"class="com.kuang.log.AfterLog"/>\n<beanid="log"class="com.kuang.log.Log"/>\n\n<!--方式三:-->\n<beanid="annotationPointCut"class="com.kuang.diy.AnnotationPointCut"/>\n<!--开启注解支持!JDK(默认proxy-target-class="false")cglib(proxy-target-class="true")-->\n<aop:aspectj-autoproxyproxy-target-class="false"/>\n\n\n<!--方式一:使用原生SpringAPI接口-->\n<!--配置aop:需要导入aop的约束-->\n<!--<aop:config>-->\n<!--<!–切入点:expression:表达式,execution(要执行的位置!*****)修饰词类方法名参数–>-->\n<!--<aop:pointcutid="pointcut"expression="execution(*com.kuang.service.UserServiceImpl.*(..))"/>-->\n<!--<!–执行环绕增加!–>-->\n<!--<aop:advisoradvice-ref="log"pointcut-ref="pointcut"/>-->\n<!--<aop:advisoradvice-ref="afterLog"pointcut-ref="pointcut"/>-->\n<!--</aop:config>-->\n\n<!--方式二:自定义类-->\n<!--<beanid="diy"class="com.kuang.diy.DiyPointCut"/>-->\n\n<!--<aop:config>-->\n<!--<!–自定义切面,ref要引用的类–>-->\n<!--<aop:aspectref="diy">-->\n<!--<!–切入点execution(返回类型包名(类名)方法名)–>-->\n<!--<aop:pointcutid="point"expression="execution(*com.kuang.service.UserServiceImpl.*(..))"/>-->\n<!--<!–通知–>-->\n<!--<aop:beforemethod="before"pointcut-ref="point"/>-->\n<!--<aop:aftermethod="after"pointcut-ref="point"/>-->\n<!--</aop:aspect>-->\n<!--</aop:config>-->\n\n</beans>\n

//方式三:使用注解方式实现AOP\n@Aspect//标注这个类是一个切面\npublicclassAnnotationPointCut{\n\n@Before("execution(*com.kuang.service.UserServiceImpl.*(..))")\npublicvoidbefore(){\nSystem.out.println("=====方法执行前=====");\n}\n\n@After("execution(*com.kuang.service.UserServiceImpl.*(..))")\npublicvoidafter(){\nSystem.out.println("=====方法执行后=====");\n}\n\n//在环绕增强中,我们可以给定一个参数,代表我们要获取并处理切入的点;\n@Around("execution(*com.kuang.service.UserServiceImpl.*(..))")\npublicvoidaround(ProceedingJoinPointjp)throwsThrowable{\nSystem.out.println("环绕前");\n\nSystem.out.println("signature:"+jp.getSignature());//获得签名\n\n//执行方法\nObjectproceed=jp.proceed();//过滤\n\nSystem.out.println("环绕后");\nSystem.out.println(proceed);\n}\n}\n=========================================================\npublicclassMyTest{\npublicstaticvoidmain(String[]args){\nApplicationContextcontext=newClassPathXmlApplicationContext("applicationContext.xml");\n//动态代理代理的是接口:注意点\nUserServiceuserService=context.getBean("userService",UserService.class);\n\nuserService.add();\n}\n}\n12、整合Mybatis

步骤:

<?xmlversion="1.0"encoding="UTF-8"?>\n<!DOCTYPEconfiguration\nPUBLIC"-//mybatis.org//DTDConfig3.0//EN"\n"http://mybatis.org/dtd/mybatis-3-config.dtd">\n<configuration>\n\n<typeAliases>\n<packagename="com.kuang.pojo"/>\n</typeAliases>\n\n<!--设置-->\n<!--<settings>-->\n<!--<settingname=""value=""/>-->\n<!--</settings>-->\n\n</configuration>\n<!--============================================================-->\n<?xmlversion="1.0"encoding="UTF-8"?>\n<beansxmlns="http://www.springframework.org/schema/beans"\nxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\nxmlns:aop="http://www.springframework.org/schema/aop"\nxsi:schemaLocation="http://www.springframework.org/schema/beans\nhttps://www.springframework.org/schema/beans/spring-beans.xsd\nhttp://www.springframework.org/schema/aop\nhttps://www.springframework.org/schema/aop/spring-aop.xsd">\n\n<!--DataSource:使用Spring的数据源替换Mybatis的配置c3p0dbcpdruid\n我们这里使用Spring提供的JDBC:org.springframework.jdbc.datasource\n-->\n<beanid="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource">\n<propertyname="driverClassName"value="com.mysql.cj.jdbc.Driver"/>\n<propertyname="url"value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT"/>\n<propertyname="username"value="root"/>\n<propertyname="password"value="123456"/>\n</bean>\n\n<!--sqlSessionFactory-->\n<beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">\n<propertyname="dataSource"ref="dataSource"/>\n<!--绑定Mybatis配置文件-->\n<propertyname="configLocation"value="classpath:mybatis-config.xml"/>\n<propertyname="mapperLocations"value="classpath:com/kuang/mapper/*.xml"/>\n</bean>\n\n<!--SqlSessionTemplate:就是我们使用的sqlSession-->\n<beanid="sqlSession"class="org.mybatis.spring.SqlSessionTemplate">\n<!--只能使用构造器注入sqlSessionFactory,因为它没有set方法-->\n<constructor-argindex="0"ref="sqlSessionFactory"/>\n</bean>\n\n</beans>\n<!--============================================================-->\n<?xmlversion="1.0"encoding="UTF-8"?>\n<beansxmlns="http://www.springframework.org/schema/beans"\nxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\nxmlns:aop="http://www.springframework.org/schema/aop"\nxsi:schemaLocation="http://www.springframework.org/schema/beans\nhttps://www.springframework.org/schema/beans/spring-beans.xsd\nhttp://www.springframework.org/schema/aop\nhttps://www.springframework.org/schema/aop/spring-aop.xsd">\n\n<!---->\n<importresource="spring-dao.xml"/>\n\n<!---->\n<beanid="userMapper"class="com.kuang.mapper.UserMapperImpl">\n<propertyname="sqlSession"ref="sqlSession"/>\n</bean>\n\n</beans>\n

publicclassUserMapperImplimplementsUserMapper{\n\n//我们的所有操作,都使用sqlSession来执行,现在都使用SqlSessionTemplate;\nprivateSqlSessionTemplatesqlSession;\n\npublicvoidsetSqlSession(SqlSessionTemplatesqlSession){\nthis.sqlSession=sqlSession;\n}\n\n@Override\npublicList<User>selectUser(){\nUserMappermapper=sqlSession.getMapper(UserMapper.class);\nreturnmapper.selectUser();\n}\n}\n==================================================================\npublicclassMyTest{\n@Test\npublicvoidtest()throwsIOException{\n\nApplicationContextcontext=newClassPathXmlApplicationContext("applicationContext.xml");\n\nUserMapperuserMapper=context.getBean("userMapper",UserMapper.class);\nfor(Useruser:userMapper.selectUser()){\nSystem.out.println(user);\n}\n}\n}\n

方式二:

<?xmlversion="1.0"encoding="UTF-8"?>\n<beansxmlns="http://www.springframework.org/schema/beans"\nxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\nxmlns:aop="http://www.springframework.org/schema/aop"\nxsi:schemaLocation="http://www.springframework.org/schema/beans\nhttps://www.springframework.org/schema/beans/spring-beans.xsd\nhttp://www.springframework.org/schema/aop\nhttps://www.springframework.org/schema/aop/spring-aop.xsd">\n\n<!--DataSource:使用Spring的数据源替换Mybatis的配置c3p0dbcpdruid\n我们这里使用Spring提供的JDBC:org.springframework.jdbc.datasource\n-->\n<beanid="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource">\n<propertyname="driverClassName"value="com.mysql.cj.jdbc.Driver"/>\n<propertyname="url"value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT"/>\n<propertyname="username"value="root"/>\n<propertyname="password"value="123456"/>\n</bean>\n\n<!--sqlSessionFactory-->\n<beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">\n<propertyname="dataSource"ref="dataSource"/>\n<!--绑定Mybatis配置文件-->\n<propertyname="configLocation"value="classpath:mybatis-config.xml"/>\n<propertyname="mapperLocations"value="classpath:com/kuang/mapper/*.xml"/>\n</bean>\n</beans>\n<!--=======================================================-->\n<?xmlversion="1.0"encoding="UTF-8"?>\n<beansxmlns="http://www.springframework.org/schema/beans"\nxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\nxmlns:aop="http://www.springframework.org/schema/aop"\nxsi:schemaLocation="http://www.springframework.org/schema/beans\nhttps://www.springframework.org/schema/beans/spring-beans.xsd\nhttp://www.springframework.org/schema/aop\nhttps://www.springframework.org/schema/aop/spring-aop.xsd">\n\n<!---->\n<importresource="spring-dao.xml"/>\n\n<!---->\n<beanid="userMapper"class="com.kuang.mapper.UserMapperImpl">\n<propertyname="sqlSession"ref="sqlSession"/>\n</bean>\n<beanid="userMapper2"class="com.kuang.mapper.UserMapperImpl2">\n<propertyname="sqlSessionFactory"ref="sqlSessionFactory"/>\n</bean>\n</beans>\n<!--===========================================================-->\n<?xmlversion="1.0"encoding="UTF-8"?>\n<!DOCTYPEmapper\nPUBLIC"-//mybatis.org//DTDConfig3.0//EN"\n"http://mybatis.org/dtd/mybatis-3-mapper.dtd">\n<mappernamespace="com.kuang.mapper.UserMapper">\n\n<selectid="selectUser"resultType="User">\nselect*frommybatis.user;\n</select>\n</mapper>\n

@Data\npublicclassUser{\nprivateintid;\nprivateStringname;\nprivateStringpwd;\n}\n===================================================================\npublicclassUserMapperImpl2extendsSqlSessionDaoSupportimplementsUserMapper{\n@Override\npublicList<User>selectUser(){\nreturngetSqlSession().getMapper(UserMapper.class).selectUser();\n}\n}\n===================================================================\npublicclassMyTest{\n@Test\npublicvoidtest()throwsIOException{\n\nApplicationContextcontext=newClassPathXmlApplicationContext("applicationContext.xml");\n\nUserMapperuserMapper=context.getBean("userMapper2",UserMapper.class);\nfor(Useruser:userMapper.selectUser()){\nSystem.out.println(user);\n}\n}\n}\n13、声明式事务1、回顾事务把一组业务当成一个业务来做;要么都成功,要么都失败!事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎!确保完整性和一致性;

事务ACID原则:

<?xmlversion="1.0"encoding="UTF-8"?>\n<beansxmlns="http://www.springframework.org/schema/beans"\nxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\nxmlns:aop="http://www.springframework.org/schema/aop"\nxmlns:tx="http://www.springframework.org/schema/tx"\nxsi:schemaLocation="http://www.springframework.org/schema/beans\nhttps://www.springframework.org/schema/beans/spring-beans.xsd\nhttp://www.springframework.org/schema/aop\nhttps://www.springframework.org/schema/aop/spring-aop.xsd\nhttp://www.springframework.org/schema/tx\nhttps://www.springframework.org/schema/tx/spring-tx.xsd">\n\n<!--DataSource:使用Spring的数据源替换Mybatis的配置c3p0dbcpdruid\n我们这里使用Spring提供的JDBC:org.springframework.jdbc.datasource\n-->\n<beanid="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource">\n<propertyname="driverClassName"value="com.mysql.cj.jdbc.Driver"/>\n<propertyname="url"value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT"/>\n<propertyname="username"value="root"/>\n<propertyname="password"value="123456"/>\n</bean>\n\n<!--sqlSessionFactory-->\n<beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">\n<propertyname="dataSource"ref="dataSource"/>\n<!--绑定Mybatis配置文件-->\n<propertyname="configLocation"value="classpath:mybatis-config.xml"/>\n<propertyname="mapperLocations"value="classpath:com/kuang/mapper/*.xml"/>\n</bean>\n\n<!--配置声明式事务-->\n<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">\n<!--<constructor-argref="dataSource"/>-->\n<propertyname="dataSource"ref="dataSource"/>\n</bean>\n\n<!--结合AOP实现事务的织入-->\n<!--配置事务通知:-->\n<tx:adviceid="txAdvice"transaction-manager="transactionManager">\n<!--给哪些方法配置事务-->\n<!--配置事务的传播特性:propagation-->\n<tx:attributes>\n<tx:methodname="add"propagation="REQUIRED"/>\n<tx:methodname="delete"propagation="REQUIRED"/>\n<tx:methodname="update"propagation="REQUIRED"/>\n<tx:methodname="select"read-only="true"/>\n<tx:methodname="*"propagation="REQUIRED"/>\n</tx:attributes>\n</tx:advice>\n\n<!--配置事务切入-->\n<aop:config>\n<aop:pointcutid="txPointCut"expression="execution(*com.kuang.mapper.*.*(..))"/>\n<aop:advisoradvice-ref="txAdvice"pointcut-ref="txPointCut"/>\n</aop:config>\n\n<beanid="userMapperImpl"class="com.kuang.mapper.UserMapperImpl">\n<propertyname="sqlSessionFactory"ref="sqlSessionFactory"/>\n</bean>\n</beans>\n<!--===========================================================-->\n<?xmlversion="1.0"encoding="UTF-8"?>\n<!DOCTYPEmapper\nPUBLIC"-//mybatis.org//DTDConfig3.0//EN"\n"http://mybatis.org/dtd/mybatis-3-mapper.dtd">\n<mappernamespace="com.kuang.mapper.UserMapper">\n\n<selectid="selectUser"resultType="User">\nselect*frommybatis.user\n</select>\n<insertid="insertUser"parameterType="User">\ninsertintomybatis.user(id,name,pwd)values(#{id},#{name},#{pwd})\n</insert>\n<deleteid="deleteUser">\ndeletefromuserwhereid=#{id}\n</delete>\n<updateid="updateUser"parameterType="User">\nupdatemybatis.userset(name,pwd)values(#{name},#{pwd})whereid=#{id};\n</update>\n</mapper>\n

publicinterfaceUserMapper{\n\nList<User>selectUser();\n\nintinsertUser(Useruser);\n\nintdeleteUser(intid);\n\nintupdateUser(Useruser);\n}\n=========================================================\npublicclassUserMapperImplextendsSqlSessionDaoSupportimplementsUserMapper{\n\npublicList<User>selectUser(){\n\nUseruser=newUser(5,"小王","123312");\nUserMappermapper=getSqlSession().getMapper(UserMapper.class);\nmapper.insertUser(user);\nmapper.deleteUser(5);\n\nreturnmapper.selectUser();\n}\n\npublicintinsertUser(Useruser){\nreturngetSqlSession().getMapper(UserMapper.class).insertUser(user);\n}\n\npublicintdeleteUser(intid){\nreturngetSqlSession().getMapper(UserMapper.class).deleteUser(id);\n}\n\npublicintupdateUser(Useruser){\nreturngetSqlSession().getMapper(UserMapper.class).updateUser(user);\n}\n}\n============================================================\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublicclassUser{\n\nprivateintid;\nprivateStringname;\nprivateStringpwd;\n}\n=============================================================\npublicclassMyTest{\n\n@Test\npublicvoidtest(){\nApplicationContextcontext=newClassPathXmlApplicationContext("spring-dao.xml");\nUserMapperuserMapperImpl=context.getBean("userMapperImpl",UserMapper.class);\n\nfor(Useruser:userMapperImpl.selectUser()){\nSystem.out.println(user);\n}\n}\n}\n

出处:https://www.cnblogs.com/wydilearn

关于spring,Spring详解的介绍到此结束,希望对大家有所帮助。

本站涵盖的内容、图片、视频等数据,部分未能与原作者取得联系。若涉及版权问题,请及时通知我们并提供相关证明材料,我们将及时予以删除!谢谢大家的理解与支持!

Copyright © 2023