Spring5框架
1、介绍
懂英文的大哥呢,建议直接一键Spring官网(Spring Framework Overview :: Spring Framework),小弟这儿也给出了地址。
当然,不是很懂英文的话还是慢慢听小弟说两句。
Spring是另一个主流的JavaWeb开发框架,当然,要接触Spring的话,你肯定得先去接触一下JavaWeb。该框架是一个轻量级的应用框架,具有很高的凝聚力和吸引力。Spring框架因为其强大的功能和牛逼的性能越来越受开发人员的喜欢。那就跟光棍五十年遇到女人一样的饥渴啊。
Spring是分层的 Java SE/EE full-stack 轻量级开源框架,以IOC(Inverse of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)为内核,使用基本的JavaBean完成以前只可能由EJB完成的工作,取代了EJB臃肿和低效的开发模式。
在实际开发中,通常服务器端采用分层架构——表现层(web)、业务逻辑层(service)、持久层(dao)。
Spring对每一层都提供了技术支持,在表现层提供了与Struts2框架的整合,在业务逻辑层可以管理事务和记录日志,在持久层可以整合Hibernate和JdbcTemplate等技术。
从设计上看,Spring框架给予了Java程序员更高的自由度(像苏菲一样,想咋跳就咋跳),所以受到了业界的一致好评。
Spring具有简单,可测试和松耦合等特点,不仅可以用于服务器端的开发,也可以应用于任何Java应用的开发中。Spring框架的主要优点如下:
1) 方便解耦,简化开发
Spring就像一个大工厂,可以将所有对象的创建和依赖关系的维护交给Spring管理(你可以想象一下养老院)
2)方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如Struts2、Hibernate、MyBatis)的直接支持。
3)降低Java EE API 的使用难度
Spring对Java EE 开发中非常难用的一些API(JDBC、JavaMail、远程调用等)都提供了封装,使这些API应用的难度大大降低。
4)方便程序的测试
Spring支持JUnit4,可以直接通过注解方便的测试Spring程序
5)AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截和运行监控等功能。
6)声明事务的支持
只需要通过配置就可以完成对事务的管理,而不用我们去手动编程。
重点:控制反转(IOC),面向切面编程(AOP)
准备工作:
-
导入jar包
-
Spring5.jer包下载https://repo.spring.io/release/org/springframework/spring/
-
配置Maven中的XML https://mvnrepository.com/artifact/org.springframework/spring-webmvc 加<dependencies>作为xml头标签 <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.2</version> </dependency> </dependencies> 直接引用xml即可
新建Maven项目,Maven下建Module
1、IOC理论推导
-
UserDao接口
public interface UserDao { public void getUser(); }
-
UserDao实现类
public class UserDaoImplement implements UserDao { @Override public void getUser() { System.out.println("这是DAO的方法!!"); } }
-
UserService业务接口
public interface UserService { public void getUser(); }
-
UserService业务实现类
public class UserServiceImplement implements UserService { private UserDao u; public void setU(UserDao u) { this.u = u; } @Override public void getUser() { u.getUser(); } }
2、Module的Jdk配置
<properties>
<maven.compiler.source>13</maven.compiler.source> <maven.compiler.target>13</maven.compiler.target>
</properties>
3、本质区别
//普通的new对象方法控制权在程序员手里,如果客户的需求很多,这种方式一直改底层,不能变成动态的满足客户,完整性破坏
// private UserDao userDao = new CatDaoImpl();
//使用java组合的特点,set方法注入对象,动态的解决了客户的需求,需要再多,也不用改底层,用户需要什么自己调用
//控制权在客户,不在我们
//控制反转 由Spring来创建对象,Spring来处理程序的生命周期,对象的实例化
@Autowired
private UserDao userDao;
//
// public void setUserDao(UserDao userDao) {
// this.userDao = userDao;
// }
第一个Spring程序
帮助文档:https://docs.spring.io/spring-framework/docs/5.2.12.RELEASE/spring-framework-reference/core.html#spring-core
-
创建一个Java类
-
resources文件夹下创建一个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="..."(相当于name) class="..."> (包名加类名) <!-- collaborators and configuration for this bean go here --> <property name="name"(属性名,字段名) value="lisi"(设置属性值)> (注:ref:引用Spring容器中创建好的对象! value:具体的值,基本数据类型!) </bean> <!-- more bean definitions go here --> </beans>
-
实例化容器
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml"); context.getBean("");注:括号里传的是个字符串,字符串对应的是XML中的id;
总结:到现在为止,我们彻底不用去程序中修改了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的IOC,一句话搞定:对象用Spring来创建,管理,装配!
2、IOC创建对象的方法:
无惨构造函数可以直接创建对象,而有参构造函数则需要使用以下方式来进行创建
<constructor-arg name="name" value="lisi"></constructor-arg>
-
参数名
第一种方法直接通过参数名来设置 <bean id="user" class="edu.hunan.net.student"> <constructor-arg name="name" value="lisi"></constructor-arg> </bean>
-
下标赋值
第二种下标赋值 <bean id="user" class="edu.hunan.net.student"> <constructor-arg index="0" value="lisi"></constructor-arg> </bean>
-
类型
第三种方式通过类型来创建,不推荐使用!! <bean id="user" class="edu.hunan.net.student"> <constructor-arg type="java.lang.String" value="zhangsan "></constructor-arg> </bean>
总结:在配置文件加载的时候,容器中管理的对象就已经初始化了!掌握了第一种方式即可,足以够用。
3、Spring配置
3.1、别名
<alias name="user" alias="student1"/>
如果我们使用了别名,也可以用别名获取到对象
3.2、Bean的配置
id:bean的唯一标识符,也就是相当于我们程序中new的对象名
class:bean对象所对应的全限定名:包名+类名
name:也是别名,而且可以同时区多了别名
<bean id="Hello" class="edu.hunan.net.HelloSpring" name="sss sd">
<property name="name" value="lisi"></property>
</bean>
<!-- IOC推荐使用注解的方式-->
<!-- 开启注解-->
<context:annotation-config></context:annotation-config>
<!-- 自动扫描 等价于<bean id="userDao" class="dao.impl.UserDaoImpl"></bean>-->
<context:component-scan base-package="dao.impl"/>
<!-- 一个ben相等于实例化一个对象,等价于 UserDaoImpl userDao = new UserDaoImpl();-->
<!-- ID等价于变量名,class等价于具体要实例化哪个对象-->
<!-- <bean id="userDao" class="dao.impl.UserDaoImpl"></bean>-->
<bean id="uservice" class="service.impl.UserServiceImpl">
<!-- 原生的set注入userService.setUserDao(new UserDaoImpl());-->
<!-- ref 等价于 userService.setUserDao(userdao) 这里的userdao相当于实例化的对象名 通过对象名找到对应的对象-->
<!-- <property name="userDao" ref="userDao"/>-->
</bean>
3.3、import
<import resource="bean1.xml"/>
<import resource="bean.xml"/>
这个import,一般用于团队的开发使用,他可以将多个配置文件,导入合并为一个
假设,现在项目中有多个人开发,这个人负责不同类的开发,不同类需要注册在不同的bean中,我们可以将用import将所有人的bean.xml合并为一个总的!!
- 小明
- 赵六
- 王五
- applictionContext.xml
使用的时候。直接使用总的!
4、依赖注入
4.1、构造器注入
<constructor-arg name="name" value="lisi"></constructor-arg>
4.2、Set方式注入【重点】
- 依赖注入:Set注入!
- 依赖:bean对象的创建依赖于容器!
- 注入:bean对象中所有属性,由容器注入!
【坏境搭建】
-
复杂类型
package edu.hunan.net; public class fuzalei { private String str; public String getStr() { return str; } public void setStr(String str) { this.str = str; } }
-
真实测试对象
bean | ref | idref | list | set | map | props | value | null private String name; private fuzalei fu; private String[] a; private List<String> b; private Map<String,String> c; private String wife; private Set<String> i; private Properties info;
-
bean
<bean id="s1" class="edu.hunan.net.student"> <property name="name" value="lisi"></property> </bean>
-
测试类
pplicationContext context =new ClassPathXmlApplicationContext("bean.xml"); student s = (student) context.getBean("s1"); System.out.print(s.getName());
完善注入
<bean id="s2" class="edu.hunan.net.fuzalei"> <property name="str" value="西安"></property> </bean> <bean id="s1" class="edu.hunan.net.student"> <!-- 普通类型注入--> <property name="name" value="lisi"></property> <!-- bean注入--> <property name="fu" ref="s2"/> <!-- 数组注入--> <property name="a"> <array> <value>红楼梦</value> <value>水浒城</value> </array> </property> <!-- List注入--> <property name="b"> <list> <value>b篮球</value> <value>b健身</value> </list> </property> <!-- map注入--> <property name="c"> <map> <entry key="g" value="李四"></entry> <entry key="c" value="张三"></entry> </map> </property> <!-- 字符串注入--> <property name="wife"> <array> <value></value> </array> </property> <!-- set注入--> <property name="i"> <set> <value>哈哈哈</value> </set> </property> <!-- Properties注入--> <property name="info"> <props> <prop key="username">王五</prop> <prop key="学号">001</prop> <prop key="password">123456</prop> </props> </property> </bean>
4.3、拓展方式注入
-
使用p:进行注入
引入包 xmlns:p="http://www.springframework.org/schema/p" <bean id="s" class="edu.hunan.net.StudentDome" p:name="王五" p:age="34"> </bean>
-
使用c:注入
xmlns:c="http://www.springframework.org/schema/c" <bean id="ss" class="edu.hunan.net.StudentDome" c:name="赵六" c:age="45"> </bean>
快速生成对象的方法
- 这是先写左边,再使用快捷键生成右边的方法。ctrl+alt+空格
- 也可以先写右边,再使用快捷键生成左边,快捷键是ctrl+alt+v
5、bean的作用域
-
scope=“singleton”:相等,无论有几个bean都是同一个bean
<bean id="s" class="edu.hunan.net.StudentDome" scope="singleton" p:name="王五" p:age="34" > </bean> scope="singleton"单例模式
-
scope=“prototype”:不相等,有几个bean就有几个bean
<bean id="ss" class="edu.hunan.net.StudentDome" scope="prototype" c:name="赵六" c:age="45"> </bean> scope="prototype"原型模式
6、Bean的自动装配【重点!】
- 自动装配是Spring满足bean依赖一种方式!
- Spring会在上下文自动寻找,并自动给bean装配属性!
在Spring中有三种配置的方式
- 在xml中显示配置
- 在java中显示配置
- 隐式的自动装配bean【重点】
6.1、在xml中显示配置
-
<bean id="cat" class="edu.hunan.net.Cat"/> <bean id="dog" class="edu.hunan.net.Dog"/> <bean id="s" class="edu.hunan.net.Person"> <property name="name" value="李四"/> <property name="cat" ref="cat"/> <property name="dog" ref="dog"/> </bean>
6.2、ByName自动装配
-
<bean id="cat" class="edu.hunan.net.Cat"/> <bean id="dog" class="edu.hunan.net.Dog"/> <bean id="s" class="edu.hunan.net.Person" autowire="byName" > <property name="name" value="李四"/> </bean>
6.3、ByType自动装配
-
<bean class="edu.hunan.net.Cat"/> <bean class="edu.hunan.net.Dog"/> <bean id="s" class="edu.hunan.net.Person" autowire="byType" > <property name="name" value="李四"/> </bean>
小结:
- byname的时候,需要保证所有的bean的id的唯一值,并且这个bean需要和自动注入的属性的set方法的值一致!
- bytype的时候,需要保证所有的bean的class的唯一值,并且这个bean需要和自动注入的属性的类型一致!
6.4、使用注解实现自动装配【重点!!】
使用须知:
-
导入约束。context约束
-
配置注解的支持:context:annotation-config/
<?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" 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"> <context:annotation-config/> </beans>
@Autowired(一个Bean对象)
<bean id="catfdfdfdf" class="edu.hunan.net.Cat"/> <bean id="dog1" class="edu.hunan.net.Dog"/>
直接在属性上使用即可!也可以在set方式上使用!
使用Autowired 我们可以不用编写set方法,前提示你这个自动装配在属性的Spring容器中存在,且符合名字ByType的格式规范!
测试代码:
@Autowired @Qualifier(value = "catfdfdfdf") private Cat cat; @Qualifier(value = "dog1") @Autowired private Dog dog; private String name;
@Qualifier(多个bean对象)
<bean id="catfdfdfdf" class="edu.hunan.net.Cat"/> <bean id="cat1" class="edu.hunan.net.Cat"/> <bean id="dog11" class="edu.hunan.net.Dog"/> <bean id="dog1" class="edu.hunan.net.Dog"/> <bean id="s" class="edu.hunan.net.Person"/>
如果@Autowired自动装配的坏境比较复杂,自动装配无法通过一个注解@Autowired完成的时候,我们可以使用@Qualifier(value = “dog1”)去配置@Autowired的使用,指定一个唯一的bean对象注入!
7、Spring注解开发
在Spring4之后,要使用注解开发,必须要保证aop的包导入了!
使用注解需要导入context约束,增加注解的支持!
<?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"
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">
<context:component-scan base-package="edu.hunan.Dao"/>
<context:annotation-config/>
</beans>
<context:component-scan base-package="edu.hunan.Dao"/>
指定要扫描的包,这个包下的注解就会生效!!
@Component:放在类上,说明这个类被Spring管理;了,就是bean!!
7.1、bean
7.2、属性如何注入
@Component//等价于<bean id="s" class="edu.hunan.Dao.User"></bean>
public class User {
@Value("lisi ")//相当于<property name="name" value="lisi"/>
public String name;
}
7.3、衍生的注解
@Component有几个衍生注解,我们在Web开发中,会按照MVC三层架构分层!
-
dao 【@Repository】
-
service 【@Service】
-
controller 【@Controller】
-
【注:这三个等价于就是@Component,只是每层有每层的写法,实际上就@Component】
这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean!
7.4、自动装配置
- @Autowired(一个Bean对象)
- @Qualifier(多个bean对象)
7.5、作用域
-
@Scope("singleton") @scope("prototype")
7.6、小结
xml与注解
xml更加万能,适合于任何场合!维护简单方便
注解不是自己类使用不了,维护相对复杂!
xml与注解最佳实践:
-
xml用来管理bean;
-
注解只负责负责完成属性的注入:
-
我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持
指定要扫描的包,这个包下的注解就会生效!! <context:component-scan base-package="edu.hunan"/> <context:annotation-config/>
8、使用Java的方式配置Spring
我们现在要完全不使用Spring的xml配置了,全部交给了Java来做!
JavaConfig是Spring的一个子项目,在Spring4之后,它成为了一个核心功能!
8.1、使用前提
- 不在使用ClassPathXmlApplicationContext(),而是使用AnnotationConfigApplicationContext
8.2、实体类
import org.springframework.stereotype.Component;
//这里这个注解的意思,就是说明这个类被Spring接管了,注册到容器中
@Component
@Import(Config2.class)
public class User {
@Value("张三")//属性注入值
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
8.3、配置类
import edu.hunan.net.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//这个也会被Spring容器接管,注册到容器中,因为他本来就是一个@Component
//@Configuration代表这是一个配置类,就和我们之前看到bean.xml
@Configuration
@ComponentScan("edu.hunan.net")
public class Config {
//注册一个Bean , 就相当于之前写的一个bean标签
//这个方法的名字,就相当于bean标签中的id属性
//这个方法的返回值,就相当于bean标签中的class属性
@Bean
public User a() {
return new User();
}//就是返回要注入bean的对象
}
8.4、测试类
import edu.hunan.Config.Config;
import edu.hunan.net.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
//如果完全使用了配置类方法去做,我们就只能通过AnnotationConfig 上下文来获取容器,通过配置类的Class对象加载!@!
ApplicationContext Context = new AnnotationConfigApplicationContext(Config.class);(注:这里传的是配置类的.Class的后缀)
User getUser = Context.getBean("a",User.class);
System.out.println(getUser.getName());
}
}
9、静态代理模式
9.1、角色分析:
- 抽象角色:一般会使用接口或者抽象类来解决---->租房
- 真实角色:被代理的角色--------->房东出租房
- 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作-------->中介
- 客户:访问代理对象的人!---------->我要租房
9.2、代码步骤:
-
接口
package edu.hunan.net; public interface zufang { public void show(); }
-
真实角色
package edu.hunan.net; public class fangdong implements zufang{ @Override public void show() { System.out.println("我要出租房!"); } }
-
代理角色
public class jingtai implements zufang{ private fangdong user; public jingtai() { } public jingtai(fangdong user) { this.user = user; } public void sess(){ System.out.println("我带你看房!!"); } public void abc(){ System.out.println("我赚中间差!!"); } public void asd(){ System.out.println("我.....!!"); } @Override public void show() { user.show();//帮房东出租房! sess(); abc(); asd(); } }
-
客户
public class MyTest { public static void main(String[] args) { //房东要出租房子 fangdong fa = new fangdong(); //代理,中介帮房东出租房子,但是呢?代理自己一般都会一些附属的操作!! jingtai jin = new jingtai(fa); //你不用找房东,直接找中介租房!! jin.show(); } }
9.3、代理模式的好处:
- 可以使真实角色的操作更加存粹!不用去关注一些公共的业务
- 公共也就交给代理角色!实现了业务的分工!
- 公共业务发生扩展的时候,方便集中管理
缺点:
- 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低
10、动态代理
-
动态代理和静态代理角色一样
-
动态代理的代理类是动态生成的,不是我们直接写好的!
-
动态代理分为两大类:基于接口的动态代理,基于类的动态代理
- 基于接口----JDK动态代理 【我们在这里使用】
-
需要了解两个类: Proxy: 代理,InvocationHandler:调用处理程序
public class ProxyService implements InvocationHandler { private User user; public void setUser(User user) { this.user = user; } //生成代理类 public Object ss(){ System.out.println("这是附属操作!"); return Proxy.newProxyInstance(this.getClass().getClassLoader(),user.getClass().getInterfaces(),this); } //处理代理类,并返回结果 @Override public Object invoke(Object o, Method method, Object[] objects) throws Throwable { b(); User invoke = (User) method.invoke(user); return invoke; } //附属的方法(自己的) public void b(){ System.out.println("我带你去看房!!"); } }
测试类
public class Test { public static void main(String[] args) { //真实角色 UserService service = new UserService(); //代理角色,现在没有 ProxyService psi = new ProxyService(); //通过调用程序处理角色来处理我们要调用的接口对象 psi.setUser(service);//你不用找房东了,直接找中介 User a = (User) psi.ss(); a.delete(); } }
动态代理的好处:
- 可以使真实角色的操作更加存粹!不用去关注一些公共的业务
- 公共也就交给代理角色!实现了业务的分工!
- 公共业务发生扩展的时候,方便集中管理
优点:
- 一个动态代理类代理的是一个接口,一般就是对应的一类业务
- 一个动态代理类可以代理多个类,只要是实现了同一个接口即可!
11、AOP【重点】
11.1、方式一:使用Spring实现Aop
-
【重点】使用AOP织入,需要导入一个依赖包!
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>
方式一:使用Spring的API接口
AfterAdvice:后置增强, 可以使用带有返回值的后置增强:AfterReturningAdvice
-
public class LogService implements AfterReturningAdvice { @Override public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { System.out.println(method.getName()+"结果为"+o); } }
BeforeAdvice:前置增强
-
public class Log implements MethodBeforeAdvice { @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println(o.getClass().getName()+"的方法"+method.getName()); } }
切入点
-
<!-- 切入点:expression:表达式 execution(要执行的位置! * * * * *)--> <aop:pointcut id="poin" expression="execution(* edu.hunan.service.UserService.*(..))"/>
环绕增强
-
执行环绕增加--> <aop:advisor advice-ref="b" pointcut-ref="poin"/> <aop:advisor advice-ref="c" pointcut-ref="poin"/>
-
11.2、配置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="a" class="edu.hunan.service.UserService"/> <bean id="b" class="edu.hunan.net.Log"/> <bean id="c" class="edu.hunan.net.LogService"/> <!-- 方式一:使用原生Spring API接口--> <!-- 在配置AOP:需要导入aop的约束--> <aop:config> <!-- 切入点:expression:表达式 execution(要执行的位置! * * * * *)--> <aop:pointcut id="poin" expression="execution(* edu.hunan.service.UserService.*(..))"/> <!-- 执行环绕增加-->advisor:通知 <aop:advisor advice-ref="b" pointcut-ref="poin"/> <aop:advisor advice-ref="c" pointcut-ref="poin"/> </aop:config> <!-- more bean definitions go here --> </beans>
11.2、方式二:自定义类实现Aop
<bean id="ss" class="edu.hunan.AOP.api"/>
<aop:config>
<aop:aspect ref="ss">
<aop:pointcut id="as" expression="execution(* edu.hunan.AOP.AopService.*(..))"/>
<aop:before method="Befor" pointcut-ref="as"/>
<aop:after method="s" pointcut-ref="as"/>
</aop:aspect>
</aop:config>
</beans>
11.3、方式三:使用注解实现AOP
-
@Aspect public class diy { @Before("execution(* edu.hunan.AopDome.UserService.*(..))") public void befoer(){ System.out.println("-----------在方法之前-----"); } @After("execution(* edu.hunan.AopDome.UserService.*(..))") public void after(){ System.out.println("---------在方法之后--------"); } }
-
<!-- 第三种方式,使用注解--> <bean id="di" class="edu.hunan.diy.diy"/> <aop:aspectj-autoproxy/>
-
测试
public static void main(String[] args) { UserService s = new UserService(); Proxya p = new Proxya(); p.setUser(s);//你不用找房东了,直接找我既中介就可以了 User a = (User) p.a(); a.show();
12、整合MyBatis
12.1、整合实现一:
-
引入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 http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
-
配置数据源替换mybaits的数据源
<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?characterEncoding=utf8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean>
-
配置SqlSessionFactory,关联MyBatis
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 关联MyBatis--> <property name="configLocation" value="MyBatis.xml"/> <property name="mapperLocations" value="classpath:edu/hunan/mapper/*.xml"/> </bean>
-
注册sqlSessionTemplate,关联sqlSessionFactory;
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean>
-
增加Mapper实现类;私有化sqlSessionTemplate
public class UserDaoImple implements mapper { private SqlSessionTemplate sqlSession; public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; } @Override public List<student> select() { mapper mapper = sqlSession.getMapper(mapper.class); return mapper.select(); } }
-
注册bean实现
<bean id="userDao" class="edu.hunan.mapper.UserDaoImple"> <property name="sqlSession" ref="sqlSession"/> </bean>
-
测试
public class Test { public static void main(String[] args) { ApplicationContext Context = new ClassPathXmlApplicationContext("Spring-bean.xml"); mapper userDao = Context.getBean("userDao", mapper.class); for (student student : userDao.select()) { System.out.println(student); } } }
结果成功输出!现在我们的Mybatis配置文件的状态!发现都可以被Spring整合!
<?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> <mappers> <mapper class="edu.hunan.mapper.mapper"/> </mappers> </configuration>