1、概述
使用spring的好处
1、通过Spring IOC容器,我们可以将对象之间的依赖关系交由Spring进行控制,
我们不用创建对象,只需声明它。
2、通过Spring AOP功能,减少代码冗余,把事务的创建放到了控制层
spring分为七大模块
- Spring AOP
- Spring ORM (HIbernate ibatis JDO)
- Spring Web (WebApplicationContext)
- Spring Dao ( JDBC Dao Support)
- Spring Context ( UI V Support)
- Spring MVC (XML JSP webViews WebFramwork)
Spring Core (BeanFactory)
控制反转(IOC)
依赖注入(AOP)
2、代理模式
概述:代理(Proxy)是一种设计模式, 提供了对目标对象另外的访问方式;即通过代理访问目标对象。 这样好处: 可以在目标对象实现的基础上,增强额外的功能操作。
解决的问题:
1、扩展程序的功能的方便性
2、面向切面编程的切面类
可分为:
静态代理
动态代理
Cglib代理
静态代理的限制条件:
1、代理的目标对象必要实现接口
2、代理对象也必须要实现接口
动态代理的限制条件:
1、 代理的目标对象也必须要实现接口
Cglib代理 的代理目标和代理对象都不需要实现接口
动态代理和Cglib代理共同点:
都需要通过父类接收对象的形式
下面是以上三个代理方式的使用
静态代理:
1、目标对象也继承与IUser重写里面的方法
2、代理继承于接口IUser并重写里面的方法,并且调用目标对象,并在该方法中调用目标对象的对应方法,代理增加的额外功能可以添加在方法前后:
局限性:只能针对特定的代理目标整体,不能拦截该类的特定方法
动态代理:
特性:可以拦截特定代理目标的不同方法
1、代理不需要继承接口,
2、 代理需要调用代理目标,编写一个方法,获取代理目标的返回值,其中用到了一个类
java.lang.reflect.Proxy;
Cglib代理:
代理目标不需要继承接口
1》、准备代理
由于代理中使用到了拦截器,所以也遵循拦截器的生命周期init -intercept
编写一个方法
public Object getProxyObject(){
//第一步引入一个构建cglib代理的子类的对象
Enhancer enhancer=new Enhancer();
//设置代理类的父类
enhancer.setSuperclass(userDao.getClass());
//设置回调
enhancer.setCallback(this);
//就可以返回这个类了
return enhancer.create();
}
重写intercept方法
@Override
public Object intercept(Object target, Method method, Object[] arg2,
MethodProxy arg3) throws Throwable {
System.out.println("增加了功能1");
Object returnValue=method.invoke(userDao, arg2);
System.out.println("增加了功能2");
return returnValue;
}
2》、编写代理类的配置文件bean.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:p="http://www.springframework.org/schema/p"
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/context
http://www.springframework.org/schema/context/spring-context.xsd">
<这里写配置代码>
</beans>
3、AOP(切面编程)
1、第一种方式使用xml文件
编写AOP类 封装了切面表达式的方法
实体类User 封装了要操作的数据
类UserDao 是对实体的操作
编写bean.xml的配置文件,注册上述的三个java类
配置aop的相关方法before after round
<aop:config>
com.qf.xml_aop.Aop
<aop:pointcut expression="execution(* xml_aop.*.*(..))" id="pt"/>
<aop:aspect ref="aop">
<aop:before method="before" pointcut-ref="pt"/>
<aop:after method="after" pointcut-ref="pt"/>
<aop:after-throwing method="throing" pointcut-ref="pt"/>
<aop:around method="round" pointcut-ref="pt"/>
</aop:aspect>
</aop:config>
第二种使用注解的方式
@Aspect指定一个类为切面类
@Pointcut(“execution(* cn.itcast.e_aop_anno..(..))”) 指定切入点表达式
@Before(“pointCut_()”)前置通知: 目标方法之前执行
@After(“pointCut_()”)后置通知:目标方法之后执行(始终执行)
@AfterReturning(“pointCut_()”) 返回后通知:执行方法结束前执行(异常不执行)
@AfterThrowing(“pointCut_()”)异常通知: 出现异常时候执行
@Around(“pointCut_()”)环绕通知:环绕目标方法执行
配置bean.xml文件
<!-- 开启注解扫描 -->
<context:component-scan base-package="cn.itcast.e_aop_anno"></context:component-scan>
<!-- 开启aop注解方式 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
总结:这种方式减少了配置,增加了维护的难度
4、Spring Dao对JDBC的支持
使用set方法注入jdbcTemplate对象:
编写bean.xml配置文件
<bean id="userDao" class="jdbc.UserDao" p:jdbcTemplate-ref="jdbcTemplate"></bean>
<!--Spring对JDBC的支持上首先 是对连接池的支持-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--下面呢就是连接池的相关配置-->
<!--配置的是数据库连接的驱动类-->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<!--注入url-->
<property name="jdbcUrl" value="jdbc:mysql:///database"></property>
<!--注入用户名-->
<property name="user" value="root"></property>
<!--注入密码-->
<property name="password" value="123456"></property>
<!--配置的是池里面连接的最大的数量-->
<property name="maxPoolSize" value="10"></property>
<!--初始化连接的数量-->
<property name="initialPoolSize" value="2"></property>
<!--统一事件能够容纳的最大的执行任务数-->
<property name="maxStatements" value="200"></property>
<!--默认连接不够的时候的增量-->
<property name="acquireIncrement" value="2"></property>
</bean>
<!--注入dataSource对象的-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--在Spring中提供的注入操作数据库的连接池-->
<property name="dataSource" ref="dataSource"></property>
</bean>
5、spring事务
配置事务必须先配置
数据库连接池,再配置事务,事务增强,Aop
<!--事物的配置-->
<!--配置的是事物的管理类-->
<bean id="txManger" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--在事物的管理类中还要注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置的是事物的增强
read-only="false":所有的事物都具有读写的权限
transaction-manager="txManger":表示的是事物的管理类要引用的是哪一个
-->
<tx:advice transaction-manager="txManger" id="txAdvice">
<tx:attributes>
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
<!--配置的是aop 因为事物都是通过aop来实现的 -->
<aop:config>
<!--配置一个切入点表达式-->
<aop:pointcut expression="execution(* jdbc_tx.UserService.*(..))" id="pt"/>
<!--要应用上面的这个事物增强-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>
6、spring和struts的整合
第一步: 导包: 需要 Spring5个核心功能包 Struts8个核心功能包
Spring整合struts的功能包 spring-web-release.jar
Struts整合Spring的功能包 Spring-struts-plugine.jar第二步: 编写配置文件:
吧struts的配置加入到Springd的配置文件中来
分别编写struts.xml beas.xml web.xml
第三步:
配置web.xml包括struts的核心过滤器和spring的配置
7、spring和hibernate整合
hibernate的xxx.hbm.xml文件配置实体的映射
首先还是在hibernate的源码包中找到hibernate的命名空间
实体Employee与数据库中表t_emp的映射
以及实体Employee与Dept实体的多对一关联
一个实体对应一个xml文件
<hibernate-mapping package="实体的全路径">
<class name="Employee" table="t_emp">
<!--配置的是主键映射-->
<id name="empId">
<generator class="native"></generator>
</id>
<property name="empName" column="empName"></property>
<many-to-one name="dept" column="deptId" class="Dept"></many-to-one>
</class>
<class name="Dept" table="t_dept">
<!--配置的是主键映射-->
<id name="deptId">
<generator class="native"></generator>
</id>
<property name="deptName" column="deptName"></property>
<set name="emps" table="t_emp" cascade="delete">
表示的是t_emp这个表中的和Dept相关的外键
<key column="deptId"></key>
这个类就是这个一对多中的这个多的类名
<one-to-many class="Employee"/>
</set>
</class>
</hibernate-mapping>
第一种整合方式
直接加载hibernate.cfg.xml文件到Spring的配置文件中来
这种方式,代码的耦合度较高
第二种方式
把hibernate的配置加入到Spring中来
下面是整合hibernate的配置代码
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- 在Spring中配置Spring的属性中配置 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="show_sql">true</prop>
<prop key="format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
<!--配置的是 *.hbm.xml文件-->
<property name="mappingDirectoryLocations">
<list>
<value>*.hbm.xml文件所在的路径</value>
</list>
</property>
</bean>