Spring使用总结

概念

它就像一个粘合剂,在实际项目中,将前后台程序粘合在一起,构建出一个完整的系统。

IOC

反转控制,依赖注入;将原先对象产生的主动权交给了Spring容器,由Spring容器来为我们完成对象的new的过程,并将对象在我们需要时交给我们。

一.依赖注入的方式:

1.setter注入(重要)

<propertyname="beanOne"><refbean="anotherExampleBean"/></property>

<propertyname="beanTwo"ref="yetAnotherBean"/>

<propertyname="integerProperty"value="1"/>

注意,getter/setter方法必须写出来

2.构造方法注入(了解)

如果有多个参数,可以指明参数的类型

<beanid="exampleBean"class="examples.ExampleBean">

<constructor-argtype="int"value="7500000"/>

<constructor-argtype="java.lang.String"value="42"/>

</bean>

如果参数是两个类型的,可以为每个参数指明索引

<constructor-argindex="0"ref="userDao"/>

<constructor-argindex="1"ref="userDao"/>

3.p命名空间注入(了解)

注意:属性都需要getter/setter方法

<beanid="zangga"class="entity.Person"p:name="张嘎"p:word="你好">

<beanid="userService"class="service.UserService"p:userDao-ref="userDao"p:userDao2-ref="userDao">

4.方法注入(用得不多)

注入不同数据类型

参见帮助文档中

Aop

面向切面编程

概念:AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。

作用:

将日志的记录,事务的处理,性能统计,安全控制等操作从业务逻辑代码中分离出来,在程序执行过程中,通过动态代理的方式织入到逻辑代码中。

1.切面:执行某一系列逻辑代码的过程

2.切入点:是根据方法和类决定在什么地方织入通知的。

3.切入程序:要动态织入的代码

aop实现方式:

方法一:通过spring自带的通知接口来实现AOP

a.前置通知MethodBeforeAdvice

定义一个前置通知的类来实现MethodBeforeAdvice接口,重写before()方法

b.后置通知AfterReturningAdvice接口

定义一个后置通知的类来实现AfterReturningAdvice接口,重写voidafterReturning(ObjectreturnValue,Methodm,Object[]args,Objecttarget)

throwsThrowable方法

c.环绕通知MethodInterceptor

publicObjectinvoke(MethodInvocationinvocation)throwsThrowable{

System.out.println("Before:invocation=["+invocation+"]");

Objectrval=invocation.proceed();

System.out.println("Invocationreturned");

returnrval;

}

d.ThrowsAdvice接口

publicvoidafterThrowing(Methodm,Object[]args,Objecttarget,ServletExceptionex){

//Dosomethingwithallarguments

}

通过ProxyFactoryBean创建AOP的代理进行引入通知

<beanid="person"class="org.springframework.aop.framework.ProxyFactoryBean"><propertyname="proxyInterfaces"><value>com.mycompany.Person</value></property>

<propertyname="target">

<beanclass="com.mycompany.PersonImpl">

<propertyname="name"><value>Tony</value></property>

<propertyname="age"><value>51</value></property>

</bean>

</property>

<propertyname="interceptorNames">

<list>

<value>myAdvisor</value>

<value>debugInterceptor</value>

</list>

</property>

</bean>

或使用<aop:config>来配置切面也可以,如下

<beanid="userService"class="biz.impl.UserBizImpl"></bean>

<beanid="userBeforeAdvice"class="advice.UserServiceBefore"></bean>

<beanid="afterUserAdvice"class="advice.AfterUserAdvice"></bean>

<beanid="userMethodInterceptor"class="advice.UserMethodInterceptor"></bean>

<beanid="userExceptionAdvice"class="advice.UserExceptionAdvice"></bean>

<aop:config>

<aop:pointcutexpression="execution(*biz.impl.*.*(..))"id="pointcut"/>

<aop:advisoradvice-ref="userBeforeAdvice"pointcut-ref="pointcut"/>

<aop:advisoradvice-ref="afterUserAdvice"pointcut-ref="pointcut"/>

<aop:advisoradvice-ref="userMethodInterceptor"pointcut-ref="pointcut"></aop:advisor>

<aop:advisoradvice-ref="userExceptionAdvice"pointcut-ref="pointcut"></aop:advisor>

</aop:config>

方法二.基于Schema的AOP,使用xml文件配置AOP

步聚:1.新建UserBiz接口,提供方法addUser()方法,delUser()方法

2.新建UserBizImpl实现类,重写addUser(),delUser()方法

3.新建AOP日志记录类LogAdvice,增加before(),after(),around(),error()方法等

publicclassLogAdvice{

publicvoidbefore(){

System.out.println("我在方法之前执行");

}

publicvoidafter(){

System.out.println("我在方法之后执行");

}

publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{

System.out.println(pjp.getTarget()+"对象的"+pjp.getSignature().getName()+"方法开始执行");

Objecttarget=pjp.proceed();

System.out.println("环绕通知");

after();

returntarget;

}

publicvoiderror(JoinPointjp){

System.out.println(jp.getSignature().getName()+"方法出错啦");

}

}

配置日志记录类:<beanid="logAop"class="aop.LogAdvice"></bean>

4.配置切面:

<aop:config>

<aop:pointcutid="pointcut"expression="execution(*biz.impl.*.*(..))"/>

<!--引用包含增强方法的Bean-->

<aop:aspectref="logAop">

<!--将before()方法定义为前置增强并引用pointcut切入点-->

<aop:beforemethod="before"pointcut-ref="pointcut"></aop:before>

<!--将afterReturning()方法定义为后置增强并引用pointcut切入点-->

<!--通过returning属性指定为名为result的参数注入返回值-->

<!--<aop:after-returningmethod="after"pointcut-ref="pointcut"returning="result"/>-->

<aop:aroundmethod="around"pointcut-ref="pointcut"></aop:around>

</aop:aspect>

</aop:config>

方法三:使用@AspectJ注解

步聚:

1.启用Spring对@AspectJ的支持,在spring中配置

<aop:aspectj-autoproxy/>

2.配置切面程序的bean:

<beanid="log"class="advice.log.LogAdvice"/>

3.声明一个切面日志记录类

@Aspect

publicclassLogAdvice{

//前置通知

@Before("execution(*biz.impl.*.*(..))")

publicvoidbefore(JoinPointjp){

TimeLimitt=(TimeLimit)Test.cac.getBean("haoShi");

t.setBeginTime(newDate());

System.out.println(jp.getSignature().getName()+"方法之前执行");

}

//后置通知

@AfterReturning("execution(*biz.impl.*.*(..))")

publicvoidafter(JoinPointjp){

TimeLimitt=(TimeLimit)Test.cac.getBean("haoShi");

t.setEndTime(newDate());

System.out.println(jp.getSignature().getName()+"方法执行结束,耗时:"+t.haoShi()+"毫秒");

}

//环绕通知

@Around("execution(*biz.impl.*.*(..))")

publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{

System.out.println(pjp.getTarget()+"对象的"+pjp.getSignature().getName()+"方法开始执行");

Objecttarget=pjp.proceed();

System.out.println("环绕通知");

returntarget;

}

//异常通知

@AfterThrowing("execution(*biz.impl.*.*(..))")

publicvoiderror(JoinPointjp){

System.out.println(jp.getSignature().getName()+"方法出错啦");

}

}

说明:@Aspect注解表示切面类

@Before("execution(*biz.impl.*.*(..))")表示前置通知

@AfterReturning(pointcut="execution(*biz.IUserBiz.*(..))",returning="returnValue")表示后置通知

@Around("execution(*biz.impl.*.*(..))")表示环绕通知

@AfterThrowing("execution(*biz.impl.*.*(..))")表示异常通知

二.生命周期

<beanid="person"class="entity.Person"init-method="init"destroy-method="destroy"scope="singleton">

1.spring容器调用无参构造方法创建对象

2.使用setter方法给属性注入值

3.init()初始化的方法被调用

4.用户手动调用的方法被执行

5.destory方法销毁对象

注意如果bean的scope="prototype"不会销毁

三.自动装配

<beanid="userService"class="service.UserService"autowire="byType"></bean>

autowire="byType":按类型进行匹配,如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配。如果存在多个该类型的bean,那么将会抛出异常,并指出不能使用byType方式进行自动装配。若没有找到相匹配的bean,则什么事都不发生,属性也不会被设置

autowire="byName":根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配

bean的作用域:singletonprototyperequestsessionglobalsession

四.注解

作用:简化xml中bean的配置

步聚:

1.引用命名空间

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context"

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

http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-3.1.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.1.xsd">

2.在applicationContext.xml中加入注解的配置

<context:annotation-config/>

<!--扫描包中注解标注的类-->

<context:component-scanbase-package="dao.impl,service,entity"></context:component-scan>

3.在类上面加入注解

在类上加注解并取名字

@Autowired写在setter方法上表示自动按名字或类型注入,配合@Qualifier("userDao")来指明要注入的组件名字

例如:

@Autowired

publicvoidsetUserDao(@Qualifier("userDao")UserDaouserDao){

this.userDao=userDao;

}

@Component("person")配在类上引号中的内容表示给组件取名字,相当于bean标签中的id属性值<beanid="person">

@Resource(name="userDao")配在属性或字段上,表示给属性进行注入,name表示要注入的组件的名字

@Controller("userService")配在action的类上

@Service("userService")配在service或biz的类上

@Repository("userDao")配在dao包下的类上

@PostConstruct注解实始化方法

@PreDestroy注解销毁方法

Spring,Hibernate,Struts框架整合

1.新建web项目,如sshDemo

2.将spring,struts2,hibernate支持的包都拷到项目的lib目录下

3.新建applicationContext.xml,struts.xml,hibernate.cfg.xml三个框架的主配置文件

4.在web.xml中整合spring和struts2

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>classpath:applicationContext.xml</param-value>

</context-param>

<listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

<filter>

<filter-name>struts2</filter-name>

<filter-class>

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

</filter-class>

</filter>

<filter>

<filter-name>OpenSessionInViewFilter</filter-name>

<filter-class>

org.springframework.orm.hibernate3.support.OpenSessionInViewFilter

</filter-class>

</filter>

<filter-mapping>

<filter-name>OpenSessionInViewFilter</filter-name>

<url-pattern>*.action</url-pattern>

</filter-mapping>

<filter-mapping>

<filter-name>struts2</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

5.写用户的注册页,登录页,以及显示用户的首页

6.写UserDaoImpl实现类完成,addUser(),getAllUser(),checkUser()等一系列的功能,并抽取UserDao接口

注意:UserDaoImpl继承HibernateDaoSupport类并实现UserDao接口

写privateSessionFactorysessionFactory;属性,getter/setter不要

7.编写UserBizImpl业务类,完成对Dao层方法的调用

写UserDao的属性,privateUserDaouserDao;提供getter/setter

8.编写UserAction类,提供login()登录的方法,getAllUser()查询所有的方法,reg()注册的方法

写biz属性:privateUserBizuserBiz;getter/setter

9.在applicationContext.xml中配置SessionFactory

<beanid="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<propertyname="configLocation">

<value>classpath:hibernate.cfg.xml</value>

</property>

</bean>

10.在applicationContext.xml中配置Dao,biz,action等,并将dao注入到biz,将biz注入到action

<!--将sessionFactory注入到userDao中-->

<beanid="userDao"class="dao.impl.UserDaoImpl">

<propertyname="sessionFactory"ref="sessionFactory"></property>

</bean>

<!--将Dao注入到Biz中-->

<beanid="userBiz"class="biz.impl.UserBizImpl">

<propertyname="userDao"ref="userDao"></property>

</bean>

<!--将biz注入到action中-->

<beanid="userAction"class="action.UserAction">

<propertyname="userBiz"ref="userBiz"></property>

</bean>

11.在struts.xml中配置action,注意,action标签中的class属性与bean中的id属性一样

<actionname="userAction"class="userAction">

<resultname="success">success.jsp</result>

<resultname="input">reg.jsp</result>

</action>

12.配声明事务

<!--事务管理器-->

<beanid="txManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<propertyname="sessionFactory"ref="sessionFactory"></property>

</bean>

<!--通知-->

<tx:adviceid="txAdvice"transaction-manager="txManager">

<tx:attributes>

<tx:methodname="find*"read-only="true"/>

<tx:methodname="search*"read-only="true"/>

<tx:methodname="query*"read-only="true"/>

<tx:methodname="save*"propagation="REQUIRED"/>

<tx:methodname="add*"propagation="REQUIRED"/>

<tx:methodname="del*"propagation="REQUIRED"/>

<tx:methodname="update*"propagation="REQUIRED"/>

<tx:methodname="do*"propagation="REQUIRED"/>

<tx:methodname="*"propagation="REQUIRED"read-only="true"/>

</tx:attributes>

</tx:advice>

<!--配切面-->

<aop:config>

<aop:pointcutid="servicePointcut"expression="execution(*biz.impl.*.*(..))"/>

<aop:advisoradvice-ref="txAdvice"pointcut-ref="servicePointcut"/>

</aop:config>

13,数据处理有Spring的模板模式

publicclassUserDaoImplextendsHibernateDaoSupportimplementsUserDao{

privateSessionFactorysessionFactory;

publicList<User>checkUser(Useruser){

returnthis.getHibernateTemplate().find("fromUserwhereusername=?andpwd=?",newObject[]{user.getUsername(),user.getPwd()});

}

publicvoidsaveUser(Useruser){

this.getHibernateTemplate().save(user);

}

publicList<User>getAllUser(){

returnthis.getHibernateTemplate().find("fromUser");

}

/*

publicList<User>checkUser(Useruser){

Stringhql="fromUserwhereusername=?andpwd=?";

Sessionsession=HibernateUtil.getSession();

Transactiontx=session.beginTransaction();

Queryquery=session.createQuery(hql);

query.setParameter(0,user.getUsername());

query.setParameter(1,user.getPwd());

List<User>userList=query.list();

tx.commit();

returnuserList;

}