spring:分层的JavaSE/EE应用full-stack轻量级开源框架,以Ioc(反转控制)和AOP(面相切面编程)为内核,提供了展示层springMVC和持久层spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的JavaEE企业应用开源框架。java
优点:mysql
一、方便解耦,简化开发web
二、AOP编程的支持spring
三、声明式事务的支持sql
四、方便程序的测试数据库
五、方便集成各类优秀框架编程
六、下降JavaEE的使用难度数组
七、源码的经典的学习范例session
程序的耦合:程序键的依赖关系,包括类之间的依赖,方法间的依赖。框架
解耦:下降程序间的依赖关系
实际开发中应该作到,编译期不依赖,运行时才依赖
解决思路:
第一步:使用反射来建立对象,而避免使用new关键字
第二步:经过读取配置文件来获取要建立的对象全限定类名。
Ioc:
概念:控制反转,把建立对象的权利交给框架,是框架的重要特征,并不是面向对象的专用术语。它包括依赖注入和依赖查找。
做用:削减计算机程序的耦合,解除咱们代码中的依赖关系。
使用:
一、配置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="accountDao" class="lianbang.wu.dao.Impl.AccountDaoImpl"></bean> <bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"></bean> </beans>
二、获取ioc核心容器,而且根据id获取对象
ApplicationContext ac = new ClassPathXmlApplicationContext("Bean.xml"); IAccountDao accountDao = ac.getBean("accountDao",IAccountDao.class); IAccountService accountService = ac.getBean("accountService",IAccountService.class);
ApplicationContext的三个经常使用实现类:
一、ClassPathXmlApplicationContext:它能够加载类路径下的配置文件,要求配置文件必须在类路径下,不在的话,加载不了
二、FileSystemXmlApplicationContext:它能够加载磁盘任意路径下的配置文件,前提是有访问权限
三、AnnotationConfigApplicationContext:它是用于读取注解建立容器的。
ApplicationContext:它在构建核心容器时,建立对象采用的策略是采用当即加载的方式,也就是说,只要一读取完配置文件立刻就建立配置文件中配置的对象,适用单例对象
BeanFactory:它在构建核心容器时,建立对象采用的策略是采用延迟加载的方式,也就是说,何时根据id获取对象了,何时才真正的建立对象,适用多例对象
建立Bean的三种方式:
第一种:使用默认构造函数建立
<bean id="accountDao" class="lianbang.wu.dao.Impl.AccountDaoImpl"></bean>
注意:若是类中没有默认构造函数,则对象没法建立
第二种:使用普通工厂类中的方法建立对象(使用某个类中的方法建立对象,并存入spring容器)
<bean id="instanceFactory" class="lianbang.wu.factory.InstanceFactory"></bean> <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
第三种:使用工厂中的静态方法建立对象(使用某个类中的静态方法建立对象,并存入spring容器)
<bean id="accountService" class="lianbang.wu.factory.StaticFactory" factory-method="getAccountService"></bean>
Bean的做用范围调整:
bean标签的scope属性
做用:用于指定bean的做用范围
取值:
singleton:单例,默认值
prototype:多例的
request:做用于web应用的请求范围
session:做用于web应用的会话范围
global-session:做用于集群环境的会话范围,当不是集群时,它就是session
<bean id="product" class="lianbang.wu.domain.Product" scope="singleton"></bean>
Bean的生命周期
单例对象
出生:当容器建立时,对象出生
活着:只要容器还在,对象一直活着
死亡:容器销毁,对象消亡
多例对象
出生:当咱们使用对象时,建立
活着:对象只要在使用过程当中就一直活着
死亡:当对象长时间不用,且没有别的对象引用时,有java的垃圾回收器回收
spring的依赖注入:
做用:维护依赖关系
能注入的数据:
一、基本类型和String
二、其余bean类型(在配置文件中或者注解配置过的bean)
三、复杂类型/集合类型
注入的方式:
一、使用构造函数提供
在bean标签的内部,使用标签constructor-arg
标签中的属性:
type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值,索引的位置从0开始
name:用于指定给构造函数中指定名称的参数赋值
value:用于提供基本类型和string类型的数据
ref:用于指定其余bean类型数据,它指的就是在spring的Ioc核心容器中出现过的bean对象
</bean> <bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"> <constructor-arg name="name" value="读者"></constructor-arg> <constructor-arg name="age" value="18"></constructor-arg> <constructor-arg name="birthday" value="now"></constructor-arg> </bean> <bean id="now" class="java.util.Date"></bean>
好处:在获取bean对象时,注入数据是必须的操做,不然对象没法建立成功
坏处:改变了bean对象的实例化方式,使咱们在建立对象时,若是用不到这些数据也必须提供。
二、使用set方法提供
在bean标签的内部,使用property
标签的属性:
name:用于指定注入时所调用的set方法名称
value:用于提供基本类型和String类型的数据
ref:用于指定其余的bean类型数据。它指的就是在spring的Ioc容器中出现过的bean对象
</bean> <bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"> <property name="name" value="读者"></property> <property name="age" value="18"></property> <property name="birthday" value="now"></property> </bean> <bean id="now" class="java.util.Date"></bean>
好处:建立对象时没有明确的限制,能够直接使用默认构造函数
坏处:若是有某个成员必须有值,则获取对象是有可能set方法没有执行
三、使用注解提供
复杂类型注入(集合,数组,propertise)
一、array,list,set
</bean> <bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"> <property name="name"> <array>aaa</array> <array>bbb</array> <array>ccc</array> </property> </bean>
注意:只需将property标签下对应的子标签改变成对应的类型
二、map
<bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"> <property name="name"> <map> <entry key="读者1" value="做品1"></entry> <entry key="读者2" value="做品2"></entry> </map> </property> </bean>
三、properties
<bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"> <property name="name"> <props> <prop key="读者1">做品1</prop> </props> </property> </bean>
常见的Ioc注解:
注意,使用注解配置时,先要修改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" 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/> <context:component-scan base-package="lianbang.wu"></context:component-scan> </beans>
一、用于建立对象的:做用就和xml配置文件中bean标签实现的功能同样
做用:把当前类对象存入spring容器中
属性:value:用于指定bean的id,当咱们不写时,默认值是当前类名,首字母小写
@Controller:通常用在表现层
@Service:通常用在业务层
@Repository:通常用在持久层
以上三个注解他们的做用和属性于Conponent是同样的,只是为咱们提供明确的三层使用的注解,使咱们的三层对象更加清晰。
二、用于注入数据的:做用就和xml配置文件中property标签实现的功能同样
@Autowired
做用;自动按照类型注入,只要容器中有惟一一个bean对象类型和要注入的变量类型匹配,就能够注入成功。若是Ioc容器中没有任何bean类型和要注入的变量类型匹配,则报错,若是Ioc容器中有多个类型匹配,根据变量名称再去匹配Ioc容器中对应类型的Id名称
出现位置:能够在变量上,也能够是方法上
细节:在使用注解注入时,set方法就不是必须的了
@Qualifier
做用:按照类中注入的基础上再按照名称注入,它在给类成员注入时不能单独使用必须与Autowired配合使用,可是在给方法参数注入时能够
属性:value:用于指定注入bean的id。
@Resource
做用:直接按照bean的id注入,它能够单独使用
属性:name:用于指定bean的id
@value
做用:用于注入基本数据类型和String类型的数据
属性:value:用于指定数据的值,它可使用spring中时spEl
spEl的写法:#{表达式}
三、用于改变做用范围:做用就和在bean标签中使用scope属性实现的功能同样
@Scope
做用:用于指定bean的做用范围
属性:value:指定范围的取值。经常使用:singleton(默认),prototype
四、和生命周期相关:做用就和bean标准中使用init-method和destroy-method的做用同样
@PreDestroy
做用:用于指定销毁方法
@PostConstruct
做用:用于指定初始化方法
Ioc的其余注解:
@Configuration
做用:当前类是一个配置类
@ConponentScan
做用:用于经过注解指定spring在建立容器时要扫描的包
属性:value:它和basePackages的做用是同样的,都是用于指定建立容器时要扫描的包。
@Bean
做用:用于把当前方法的返回值做为bean对象,存入spring的ioc容器中
属性:name:用于指定Bean的id,默认值是当前方法的名称
注意:当使用注解配置方法,若是方法有参数,spring框架会去容器中查找有没有可用bean对象,和Autowired机制同样。
使用注解配置类:
ApplicationContext ac = new AnnotationConfigApplicationContext(springConfig.class);
@import
做用:用于导入其余配置类
@propertySource
做用:用于指定properties文件的位置
属性:value,指定文件的名称和路径,classpath,表示类路径下
Spring整合Junit
第一步:导入spring整合Junit的jar包
第二步:使用Junit提供的一个注解把原有的main方法替换成spring提供的
@Runwith
第三步:告知spring的运行器,spring的ioc建立是基于xml仍是注解的,而且说明位置
@ContextConfiguration
location:指定xml文件的位置,加上classpath关键字,表示在类路径下
classes:指定注解类所在的位置
注意:当咱们使用spring 5.X版本的时候,要求Junit的jar必须是4.12以上
AOP:
概念:面向切面编程,它就是把完美程序重复的代码抽取出来,在须要执行的时候,使用动态代理技术,在不修改源码的基础上,对完美的已有方法进行加强。
相关术语:
Joinpoint:链接点:简单的说就是能够被加强的方法
Pointcut:切入点:简单的说就是被加强了的方法
Advice:通知:拦截到joinpoint以后所要作的事情,通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。
Introduction:引介:是一种特殊的通知,在不修改代码的前提下,能够在运行期为类动态的添加一些方法。
Target:目标对象:被代理对象
Weaving:把加强应用到目标对象来建立新的代理对象的过程
Proxy:代理:一个类被AOP织入加强后,就产生一个结果代理类
Aspect:切面:切入点和通知的结合
基于XML方式:
一、把切面添加到Ioc容器
<bean id="logger" class="lianbang.wu.utils.Logger"></bean>
二、使用aop:config标签代表开始AOP的配置
三、使用aop:aspect标签代表配置切面
id:给切面提供一个惟一标识
ref:是指定通知类bean的id
四、在aop:aspect标签的内部使用对应标签来配置通知的类型
aop:before:表示配置前置通知,在切入点方法执行以前执行
method:指定logger类中哪一个方法是前置通知
pointcut:用于指定切入点表达式,该表达式的含义指的是对业务层中哪些方法加强
切入点表达式的写法:execution(表达式)
表达式:访问修饰符 返回值 包名.类名.方法名(参数列表)
全通配写法 * *..*.*(..)
实际开发一般写法:* 包名.*.*(..)
aop:after-returning:后置通知,在切入点方法执行以后执行
aop:after-throwing:异常通知,在切入点执行产生异常以后执行
aop:after:最终通知,不管切入点方法是否正常执行,它都会在后面执行
aop:around:环绕配置,当配置环绕通知以后,须要在切入点方法中传入参数,明确调用切入点等等
<aop:config> <aop:aspect id="logAdvice" ref="logger"> <aop:before method="printLog" pointcut="execution(public void lianbang.wu.service.Impl.AccountServiceImpl.saveAccount())"></aop:before> </aop:aspect> </aop:config> </beans>
基于注解方式:
@Component("logger") @Aspect //@EnableAspectJAutoProxy public class Logger { @Pointcut("execution(* lianbang.wu.service.Impl.*.*(..))") private void pt1(){}; @Before("pt1()") public void printLog(){ System.out.println("Logger类中的方法开始记录日志。。。"); }
注意:环绕通知必须传入ProceedingJoinPoint类型参数
@Around("pt1()") public void around(ProceedingJoinPoint joinPoint){ System.out.println("前置通知"); try { joinPoint.proceed(); } catch (Throwable throwable) { throwable.printStackTrace(); } System.out.println("后置通知"); }
jdbcTemplate
做用:用于和数据库交互,实现对表的CRUD操做
public class JdbcTemplateDemo { public static void main(String[] args) { //0、准备数据源 DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(); driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver"); driverManagerDataSource.setUrl("jdbc:mysql://localhost:3306/eesy"); driverManagerDataSource.setUsername("root"); driverManagerDataSource.setPassword("120609"); //一、建立对象 JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(driverManagerDataSource); //二、执行操做 jdbcTemplate.execute("insert into account(id,uid,money)value (5,46,1000)"); } }
补充:能够将上面2个new出来的对象放入Ioc对象,在进行调用