Spring详细概述----->从入门到吃灰

tech2024-03-25  8

1.Spring
1.1 Spring在Maven中的依赖:
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.7.RELEASE</version> </dependency> Spring与Mybatis整合: <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-Jdbc</artifactId> <version>5.2.7.RELEASE</version> </dependency>
1.2 Spring优点
Spring 是一个开源的免费框架(容器);spring 是一个轻量级、非入侵式的框架;Spring控制反转(IOC)、面向切面编程(AOP);支持事务的处理、和对框架整合;
1.3 Spring的xml配置

在IOC(控制反转)中我们不需要new对象,由Spring来创建对象,主要通过在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"> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions go here --> </beans>

id和class的作用:

2.1 该id属性是标识单个bean定义的字符串;

2.2 该class属于bean的类型,并且使用完全限定类名;

实例:

<?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"> <bean id="MybatisDaoImpl" class="com.muzi.Dao.MybatisDaoImpl"/> <bean id="OrealDaoImpl" class="com.muzi.Dao.OrealDaoImpl"/> <bean id="UserServiceImpl" class="com.muzi.Service.UserServiceImpl"> <property name="userDao" ref="OrealDaoImpl"/> </bean> </beans>

注:在beans.xml中我们只需其,就可以实现对数据的调用。完全实现了对控制的反转且property为属性

注:value为具体的值,基本的数据类型——ref为引用spring容器中创建好的对象

2. IOC
2.1 IOC创建对象方式

我们创建实体类的时候,需要构造无参(默认存在)、有参以及get、set方法;

在beans.xml中实现对其配置bean定义对应于组成应用程序的实际对象。通常,您定义服务层对象,数据访问对象(DAO),表示对象(例如Struts Action实例),基础结构对象(例如Hibernate SessionFactories,JMS Queues等。只需要在xml中为其注入依赖,就可以在测试类中使用;

实例化对象的使用,ApplicationContext context = new ClassPathXmlApplicationContext(“services.xml”, “daos.xml”);其中可以放置一个或多个.xml的beans文件;通过context来实现对方法的调用;

注:只需要将服务层、Dao(数据访问对象)、表示对象基础结构对象注入到依赖中就可以在测试中实现

2.2 使用有参构造创建对象

使用下标创建

<bean id="User" class="com.muzi.pojo.User"> <constructor-arg index="0" value="好好学Java"/> </bean>

使用类型创建

<bean id="User" class="com.muzi.pojo.User"> <constructor-arg type="java.lang.String" value="萨达萨达"/> </bean>

注:使用类型创建时Type的值是固定g

使用参数名来设置(使用最多的)

<bean id="User" class="com.muzi.pojo.User"> <constructor-arg name="uname" value="小木木"/> </bean>
3. Spring配置
在beans种有很多的标签:bean为主要创建类、import是可集合所有的beans.xml的文件;还有alias的起别名,name的别名和alias的别名都可以在容器中使用(且name可以取多个别名);
4. 依赖注入

在依赖注入中有\ \ \ 等;

其中map注入于其他注入的区别

<property name="card"> <map> <entry key="身份证" value="145252252525236523"/> <entry key="银行卡" value="458523962563256352"/> <entry key="学生证" value="1253652698"/> </map> </property>

map在实体中有关键字和value值;而其他的注入中没有;

其他注入list/array

<property name="books"> <array> <value>《西游记》</value> <value>《水浒传》</value> <value>《红楼梦》</value> <value>《三国志》</value> </array> </property> <property name="hobbys"> <list> <value>听歌</value> <value>敲代码</value> <value>兜风</value> </list> </property>

注:其中为null的也是注入的标签

<property name="wife"> <null/> </property>

自定义的输入,也是具有关键字

<property name="info"> <props> <prop key="性别"></prop> <prop key="自评">我是一个爱好学习的人</prop> </props> </property>

5.测试结果

Student{name='木子', address=Address{address='山西太原'}, hobbys=[听歌, 敲代码, 兜风], games=[lol, coc, qaq], card={身份证=145252252525236523, 银行卡=458523962563256352, 学生证=1253652698}, books=[《西游记》, 《水浒传》, 《红楼梦》, 《三国志》], wife='null', info={性别=女, 自评=我是一个爱好学习的人}}
4.1 完善注入
<?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"> <bean id="Address" class="com.muzi.pojo.Address"> <property name="address" value="山西太原"/> </bean> <bean id="Student" class="com.muzi.pojo.Student"> <!--普通注入——第一种--> <property name="name" value="木子"/> <!--bean注入--> <property name="address" ref="Address"/> <!--数组--> <property name="books"> <array> <value>《西游记》</value> <value>《水浒传》</value> <value>《红楼梦》</value> <value>《三国志》</value> </array> </property> <!--list集合--> <property name="hobbys"> <list> <value>听歌</value> <value>敲代码</value> <value>兜风</value> </list> </property> <!--map集合--> <property name="card"> <map> <entry key="身份证" value="145252252525236523"/> <entry key="银行卡" value="458523962563256352"/> <entry key="学生证" value="1253652698"/> </map> </property> <!--set集合--> <property name="games"> <set> <value>lol</value> <value>coc</value> <value>qaq</value> </set> </property> <!--Properties--> <property name="info"> <props> <prop key="性别"></prop> <prop key="自评">我是一个爱好学习的人</prop> </props> </property> <!--null注入--> <property name="wife"> <null/> </property> </bean> </beans>
5. C/P空间命名注入

注:在使用p空间和c空间时,需要导入xml约束,不能直接使用

xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"

使用P空间注入信息

<bean id="User" class="com.muzi.pojo.User" p:name="桃夭" p:age="18"/>

使用C空间注入信息

<!--在使用c空间注入信息时,需要在实体类中有构造方法Construct--> <bean id="User2" class="com.muzi.pojo.User" c:name="柳公子" c:age="20"/>
6. bean的生命周期
6.1 单例模式

(Spring的默认机制)

概念:singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实例。

<bean id="hi" class="com.test.Hi" init-method="init" scope="singleton"> 1. ApplicationContext context = new FileSystemXmlApplicationContext("applicationContext.xml"); 2 Hi hi1 = (Hi) context.getBean("hi"); 3 Hi hi2 = (Hi) context.getBean("hi"); 4 System.out.println(hi1); 5 System.out.println(hi2);

只有一个共享实例存在,只对一个bean返回实例;

二者的值一样;true

6.2 原型模式

概念:prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new 对象。

<bean id="hi" class="com.test.Hi" init-method="init" scope="prototype">

二者的值不一样;false;

6.3 其他模式

其余的requerst、session、application这些只能在web中使用;

7. Bean的自动装配
自动装配是Spring满足bean依赖一种方式;Spring会在上下文中自动寻找,并自动给bean装配属性;
7.1 ByName自动装配
<!--autowire可以通过byName来实现,是通过id名寻找set名更改id名则不能使用--> <bean id="people" class="com.muzi.pojo.People" autowire="byType"> <!--autowire="byName"--> <property name="name" value="木木"/>
7.2 ByType自动装配
<bean class="com.muzi.pojo.Dog"/> <bean class="com.muzi.pojo.Cat"/> <!--autowire可以通过byType来实现,是通过属性类型来实现,无需id名也可实现--> <bean id="people" class="com.muzi.pojo.People" autowire="byType"> <!--autowire="byName"--> <property name="name" value="木木"/>
7.3 小结
byName的时候,需要保证bean中的id名唯一,与自动注入的set方法名一致;byType的时候,需要保证bean中class唯一,与自动注入的属性类型一致;
7.4 注解自动装配

使用注解需要条件:

导入约束:

<?xml version="1.0" encoding="UTF-8"?>

- ==配置注解的支持:== ```xml <context:annotation-config/>

@AutoWire

通过class来实现注解的注入

【通常】可以直接在属性上使用;也可以在set方法上使用;

@Nullable与@Autowired(required = false))作用相同,都是可以使属性的值为空;且@Nullable可以设置在有参构造方法;

public People(@Nullable String name) { this.name = name; }

当属性名和bean中的注入id名不一致时,可是联合使用@Qualifier(value = “id名”)与@AutoWire来实现;给予他指定的id名;

@Autowired @Qualifier(value = "cat22") private Cat cat; @Autowired @Qualifier(value = "dog12") private Dog dog;

@Resouce

在使用的时候先查询id的name在去查询class,当属性和注入名不一样时,则通过bytype实现;二者都实现不了则报错;

@resource(name=“xxx”)指定id名

@Resource(name = "cat22") <bean id="cat22" class="com.muzi.pojo.Cat"/>
8. Spring注解开发
8.1 注解类型

@Component—组件放在实体类中,被spring管理,其作用相当于;

@Component //component就相当于在xml文件中所配置<bean id="user" class="com.muzi.pojo.user"> public class User { public String name; }

@Value(“值”),注入值为属性使用注解

public class User { @Value("诸葛研") //相当于<bean id="user" class="com.muzi.pojo.user"> // <property name="name" value="诸葛研"> // </bean> public String name; }
8.2 衍生注解
@Component的几个衍生注解,在web开发中,会用到mvc三层架构;Dao【@repository】Service【@Service】Controller【@Controller】

这四个注解的功能相同,都是将类注入到spring中,装备bean

8.3 作用域

注解@scope设置作用域单例(single)还是原型(prototype)

@Scope("single") //或是prototype public class User { class="com.muzi.pojo.user"> public String name; }
8.4 小结

xml与注解:

xml比较万能,能适用于任何场合;注解只能在自己的类中使用,维护想对复杂;

xml与注解的最佳实现:

xml控制bean;

注解只管属性的注入;

==注:==要使注解生效,必须要开启注解支持;

<!--启动注解配置--> <context:annotation-config/> <!--扫描注解的下的包--> <context:component-scan base-package="com.muzi"/>
9.JavaConfig实现注解
9.1 获取容器方法
public class MyTest { @Test public void Test(){ ApplicationContext context = new AnnotationConfigApplicationContext(UserConfig.class);//配置类 User user = context.getBean("MyUser", User.class); System.out.println(user.getName()); } }

==注:==容器中获取的配置类的class获取UserConfig.class;getbean获取的是方法名;

9.2 配置文件
//他们都是组件会被spring容器托管,注册到容器中,因为其本身也是@component //@Configuration就相当于beans.xml; @Configuration @ComponentScan("com.muzi.pojo")//扫描包 @Import(UserConfig1.class)//导入其他配置 public class UserConfig { @Bean public User MyUser(){ return new User();//返回注入的bean对象 } }
10.代理模式

代理模式的好处:

可以使真实角色的操作更加纯粹,不用去关注一些公共的业务;公共业务交给代理角色,实现业务的分工;公共业务发生扩展的时候,方便管理;

缺点:

当真实角色增加时,代理角色也会增加,会增加代码量;开发效率变低;
10.1 动态代理

InvocationHandler:由代理实例处理程序实现的接口;实现类时他会调用里面的程序方法invoke;

Objectinvoke(Object proxy, 方法 method, Object[] args) 处理代理实例上的方法调用并返回结果。

Proxy:提供创建动态代理类和实例的静态方法,他也是由这些方法创建的所有动态代理类的超类;

动态代理分为两大类:基于接口的动态代理和基于类的动态代理;

基于接口——JDK动态代理基于类——cglib (高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口)java字节码实现——javasist

动态代理的好处:

可以使真实角色的操作更加纯粹,不用去关注一些公共的业务;公共业务交给代理角色,实现业务的分工;公共业务发生扩展的时候,方便管理;一个动态代理类代理的是一个接口,对应的就是一类业务;

代理的类

import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyInvocationHandler implements InvocationHandler { //被代理接口 private Object tager; public void setTager(Object tager) { this.tager = tager; } //生成得到代理类 //this.getClass().getClassLoader()获得本地类 //tager.getClass().getInterfaces()获得本地类接口 public Object getproxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),tager.getClass().getInterfaces(),this); } //处理代理实类,并返回结果 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object invoke = method.invoke(tager); //调取该方法名字 log(method.getName()); return invoke; } //添加其他方法 public void log(String msg){ System.out.println("【debug】使用了"+msg+"方法"); } }

测试

public class Client { public static void main(String[] args) { //真实角色 UserServiceImpl userService = new UserServiceImpl(); //代理角色 ProxyInvocationHandler pih = new ProxyInvocationHandler(); //实体类方法 pih.setTager(userService); //代理类 UserService proxy = (UserService) pih.getproxy(); proxy.add(); proxy.select(); } }
11. AOP实现方式
11.1 方式一

原生的API接口实现

aop支持的依赖

<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>

使用aop的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--> <bean id="userService" class="com.muzi.Service.UserServiceImp"/> <bean id="afterLog" class="com.muzi.Log.AfterLog"/> <bean id="beforeLog" class="com.muzi.Log.BeforeLog"/> <!--方法1:使用原生的API接口--> <!--配置aop:需导入aop约束--> <aop:config> <!--切入点 id为名称 expression为表达式 execution为要执行的位置--> <aop:pointcut id="pointcut" expression="execution(* com.muzi.Service.UserServiceImp.*(..))"/> <!--执行环绕增加--> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/> </aop:config>

测试实现

public class MyTest { @Test public void Test1(){ ApplicationContext context = new ClassPathXmlApplicationContext("Application.xml"); //动态代理代理的是接口 UserService userService = context.getBean("userService", UserService.class); userService.delete(); } }
11.2方式二

使用自定义方法实现——利用切面

自定义类——方法

public class diy { public void before(){ System.out.println("====方法执行前===="); } public void after(){ System.out.println("===方法执行后===="); } }

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: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--> <bean id="userService" class="com.muzi.Service.UserServiceImp"/> <bean id="afterLog" class="com.muzi.Log.AfterLog"/> <bean id="beforeLog" class="com.muzi.Log.BeforeLog"/> <!--方法二DIY--> <bean id="diy" class="com.muzi.Diy.diy"/> <aop:config> <!--切面 自定义ref是引用的类--> <aop:aspect ref="diy"> <!--切入点--> <aop:pointcut id="pointcut" expression="execution(* com.muzi.Service.UserServiceImp.*(..))"/> <!--通知--> <aop:before method="after" pointcut-ref="pointcut"/> <aop:after method="after" pointcut-ref="pointcut"/> </aop:aspect> </aop:config> </beans>
11.3方式三

使用注解式实现aop

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 https://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:annotation-config/> <!--扫描指定的包--> <context:component-scan base-package="com.muzi"/> <!--开启aop注解支持--> <aop:aspectj-autoproxy/> </beans>

注解实现自定义类

package com.muzi.Diy; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.*; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; @Configuration @Aspect @Component public class AnnotationPointcut { @Before("execution(* com.muzi.Service.UserServiceImp.*(..))") public void before(){ System.out.println("====方法执行前===="); } @After("execution(* com.muzi.Service.UserServiceImp.*(..))") public void after(){ System.out.println("===方法执行之后==="); } //环绕增强中,我们可以给定参数,代表我们要处理切入的点 @Around("execution(* com.muzi.Service.UserServiceImp.*(..))") public void around(ProceedingJoinPoint jp) throws Throwable { System.out.println("环绕前"); //获得签名 Signature signature = jp.getSignature(); System.out.println(signature+"signature"); //执行方法 Object proceed = jp.proceed(); System.out.println("环绕后"); } } 测试结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DZqMtvIw-1599125270315)(C:\Users\暴走小萝莉\AppData\Roaming\Typora\typora-user-images\image-20200630161025872.png)]

11.4 Spring通知
前置通知:在目标方法执行之前执行的通知;后置通知:在目标方法执行之后执行的通知;环绕通知:在目标方法执行之前或是之后都可以执行额外代码的通知;异常通知:在目标方法抛出异常时执行的通知;最终通知:在目标方法执行之后执行的通知,最终通知与后置通知不同,后置通知方法正常返回后执行,最终通知无论如何都会在方法调用后执行;

12. Spring与Mybatils整合

12—1:方式一
12.1 Maven依赖架包
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>Spring</artifactId> <groupId>com.muzi</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>Spring_12</artifactId> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.26</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.5</version> </dependency> <!--spring操作数据需要spring-jdbc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.7.RELEASE</version> </dependency> </dependencies> </project>
12.2 创建实体类
package com.muzi.pojo; public class User { private int id; private String username; private String sex; private String address; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}'; } public User() { } }
12.3 映射(接口、实现类、映射配置文件)

接口

public interface UserMapper { List<User> getAll(); /*接口的方法名必须与映射的id名一致*/ User getByidUser(int id); }

映射文件

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.muzi.Mapper.UserMapper"> <select id="getAll" resultType="user"> select * from user ; </select> <!--映射语句下的id必须与接口的方法名一致--> <select id="getByidUser" resultType="user" parameterType="int"> select * from mybatis.user where id=#{id}; </select> </mapper>

实现类

public class UserMapperImp implements UserMapper { private SqlSessionTemplate sqlSession; /*原来都使用sqlsession 现在使用SqlSessionTemplate去实现*/ public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; } /*想要实现哪个方法直接实现就好*/ public List<User> getAll() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.getAll(); } public User getByidUser(int id) { UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.getByidUser(id); } }
12.4 数据源配置

Mybatis-Config.xml配置

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeAliases> <package name="com.muzi.pojo"/> </typeAliases> </configuration> <!-- <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings--> <!--使用typeAliases可以给实体类别名--> <!-- <typeAliases> &lt;!&ndash; <typeAlias type="com.muzi.entity.User" alias="User"/>&ndash;&gt; &lt;!&ndash;使用package扫描包名,但没注解的话 只能使用类的小写为别名(大小写均可)&ndash;&gt; <package name="com.muzi.pojo"/> </typeAliases>-->

Mybatis-Sping.xml 配置

SqlSessionFactory

SqlSessionTemplate

注:需要导入Spring配置的文件

<?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"> <!--dataSource 使用spring数据源替换mybatis配置 c3p0\dbcp\druid class使用spring提供的jbdc DriverManagerDataSource驱动管理数据源--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!--SqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!--绑定mybatis配置文件--> <property name="configLocation" value="classpath:Mybatis-Config.xml"/> <property name="mapperLocations" value="classpath:com/muzi/Mapper/*.xml"/> </bean> <!--SqlSessionTemplate:就是SqlSession我们使用的--> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory"/> <!--只能使用构造器注入sqlSessionFactory没有set方法--> </bean> 注册实现类 <bean id="userMapper" class="com.muzi.Mapper.UserMapperImp"> <property name="sqlSession" ref="sqlSession"/> </bean> </beans>
12.5 测试
public class MyTest { @Test public void getAll(){ ApplicationContext context = new ClassPathXmlApplicationContext("Spring-dao.xml"); UserMapper userMapper = context.getBean("userMapper", UserMapper.class); List<User> getAll = userMapper.getAll(); for (User user : getAll) { System.out.println(user); } } @Test public void getByidUser(){ ApplicationContext context = new ClassPathXmlApplicationContext("Spring-dao.xml"); UserMapper mapper = context.getBean("userMapper", UserMapper.class); User User = mapper.getByidUser(20); System.out.println(User); } }
12—2:方式二

使用SqlSessionDaoSupport支持实现

实现类配置

public class UserMapperImp2 extends SqlSessionDaoSupport implements UserMapper { public List<User> getAll() { /*UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.getAll();*/ return getSqlSession().getMapper(UserMapper.class).getAll(); } public User getByidUser(int id) { return getSqlSession().getMapper(UserMapper.class).getByidUser(id); } }

调用getSqlSession方法可以得到SqlSessionTemplate,后执行sql语句;注入的name为工厂

<bean id="userMapper2" class="com.muzi.Mapper.UserMapperImp2"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </ben>

13. 事务

事务要么都成功,要么都失败

acid原则:

A——原子性:事务是否完整的完成;C——一致性:事务在系统完整性中实施一致性;I——隔离性:多个业务操作同一个资源,防止数据损坏;D——持久性:事务被提交,就会被永久存储,结果都不会被影响;

13.1 声明式事务(使用AOP切入)

在Spring—Dao.xml的配置

<!--配置声明式事务--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource" /> </bean> <!--结合aop实现事物的织入--> <!--配置事务通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!--配置事务传播特性 propagation--> <tx:method name="insert"/> <tx:method name="select" propagation="REQUIRED"/> <tx:method name="*"/> </tx:attributes> </tx:advice> <!--配置事务切入点--> <aop:config> <!--mapper下面的所有类,所有方法--> <aop:pointcut id="txPoincut" expression="execution(* com.muzi.Mapper.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoincut"/> </aop:config>

13.2 编辑式事务

使用 @Autowired 和 @Qualifier 注解执行自动装配

使用 @Autowired 注解进行装配,只能是根据类型进行匹配。@Autowired 注解可以用于 Setter 方法、构造函数、字段,甚至普通方法,前提是方法必须有至少一个参数。@Autowired 可以用于数组和使用泛型的集合类型。然后 Spring 会将容器中所有类型符合的 Bean 注入进来。@Autowired 标注作用于 Map 类型时,如果 Map 的 key 为 String 类型,则 Spring 会将容器中所有类型符合 Map 的 value 对应的类型的 Bean 增加进来,用 Bean 的 id 或 name 作为 Map 的 key。

@Autowired 标注作用于普通方法时,会产生一个副作用,就是在容器初始化该 Bean 实例的时候就会调用该方法。当然,前提是执行了自动装配,对于不满足装配条件的情况,该方法也不会被执行。

当标注了 @Autowired 后,自动注入不能满足,则会抛出异常。我们可以给 @Autowired 标注增加一个 required=false 属性,以改变这个行为。另外,每一个类中只能有一个构造函数的 @Autowired.required() 属性为 true。否则就出问题了。如果用 @Autowired 同时标注了多个构造函数,那么,Spring 将采用贪心算法匹配构造函数 ( 构造函数最长 )。

@Autowired 还有一个作用就是,如果将其标注在 BeanFactory 类型、ApplicationContext 类型、ResourceLoader 类型、ApplicationEventPublisher 类型、MessageSource 类型上,那么 Spring 会自动注入这些实现类的实例,不需要额外的操作。

当容器中存在多个 Bean 的类型与需要注入的相同时,注入将不能执行,我们可以给 @Autowired 增加一个候选值,做法是在 @Autowired 后面增加一个 @Qualifier 标注,提供一个 String 类型的值作为候选的 Bean 的名字。

TomCat控制台乱码问题:
-Dfile.encoding=UTF-8

Mapper..(…))"/> <aop:advisor advice-ref=“txAdvice” pointcut-ref=“txPoincut”/> </aop:config>

13.2 编辑式事务 ### 使用 @Autowired 和 @Qualifier 注解执行自动装配 使用 @Autowired 注解进行装配,只能是根据类型进行匹配。@Autowired 注解可以用于 Setter 方法、构造函数、字段,甚至普通方法,前提是方法必须有至少一个参数。@Autowired 可以用于数组和使用泛型的集合类型。然后 Spring 会将容器中所有类型符合的 Bean 注入进来。@Autowired 标注作用于 Map 类型时,如果 Map 的 key 为 String 类型,则 Spring 会将容器中所有类型符合 Map 的 value 对应的类型的 Bean 增加进来,用 Bean 的 id 或 name 作为 Map 的 key。 @Autowired 标注作用于普通方法时,会产生一个副作用,就是在容器初始化该 Bean 实例的时候就会调用该方法。当然,前提是执行了自动装配,对于不满足装配条件的情况,该方法也不会被执行。 当标注了 @Autowired 后,自动注入不能满足,则会抛出异常。我们可以给 @Autowired 标注增加一个 required=false 属性,以改变这个行为。另外,每一个类中只能有一个构造函数的 @Autowired.required() 属性为 true。否则就出问题了。如果用 @Autowired 同时标注了多个构造函数,那么,Spring 将采用贪心算法匹配构造函数 ( 构造函数最长 )。 @Autowired 还有一个作用就是,如果将其标注在 BeanFactory 类型、ApplicationContext 类型、ResourceLoader 类型、ApplicationEventPublisher 类型、MessageSource 类型上,那么 Spring 会自动注入这些实现类的实例,不需要额外的操作。 当容器中存在多个 Bean 的类型与需要注入的相同时,注入将不能执行,我们可以给 @Autowired 增加一个候选值,做法是在 @Autowired 后面增加一个 @Qualifier 标注,提供一个 String 类型的值作为候选的 Bean 的名字。 ###### TomCat控制台乱码问题:

-Dfile.encoding=UTF-8

最新回复(0)