学习Spring笔记七





以spring IOC为核心,来管理其它框架的重要对象,因为IOC就是用来管理对象的。








annotation方式整合三大框架  start——————————————————


三个框架都有各自的annotation


struts2  @Action  @Result
spring  @component  @Resource
hibernate  @Entity  


那么在Spring统一管理当中,如何让这些注解生效呢?


下面代码在三大框架整合的基础上修改


1.spring自己的注解如何生效,applicationContext.xml代码如下
  <context:component-scan base-package="com.bjsxt"></context:component-scan>   //用了这个扫描器,普通的bean的定义可以不加了,下面的就注释掉吧
  <!--
  <bean id="userDao" class="com.bjsxt.dao.UserDao">
<property name="sessionFactory" ref="sessionFactory"></property>
  </bean>
  <bean id="userAction" class="com.bjsxt.action.UserAction" scope="prototype">
<property name="hibernateTemplate" ref="hibernateTemplate"></property>
  </bean>-->




  <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="packagesToScan">
<list>
   <value>com.bjsxt.po</value>
</list>
</property>


<property name="hibernateProperties">  //全局参数
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.url">jdbc:mysql://locahost:3306/test</prop>
<prop key="hibernate.connection.username">root</prop>
<prop key="hibernate.connection.password">1234</prop>

<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
  </bean>


  <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemple">
<property name="sessionFactory" ref="sessionFactory"></property>
  </bean>


  <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
  </bean>


  <tx:annotation-driven transaction-manager="txManager"/>


</bean>




2.UserAction.java
@Component
public class UserAction{
private User user;


public User getUser(){
retrun user;
}


public void setUser(User user){
this.user = user;
}

private HibernateTemplete hibernateTemplate;


public HibernateTemplate getHibernateTemplate(){
return hibernateTemplate;
}
@Resource(name="hibernateTemplate")
public void setHibernateTemplate(HibernateTemplate hibernateTemplate){
this.hibernateTemplate = hibernateTemplate;
}

@Transactional
public String add(){
hibernateTemplate.save(user);  
return null; 
}


//这个方法测试时可以关闭或打开,查询所有
public String findAll(){
List<User> list = hibernateTemplate.find("from User");
for(Iterator iterator = list.iterator(); iterator.hasNext();){
User user = (User) iterator.next();
System.out.println(user.getName()+"--"+user.getId());
}
return null;
}




private String name;
public String findByCondition(){
List<User> list = hibernateTemplate.find("from User u where u.name=?",new Object[]{name});  //逗号后的值对应前面那个问号
for(Iterator iterator = list.iterator();iterator.hasNext();){
User user = (User) iterator.next();
System.out.println(user.getName());
}
return null;
}


public String getName(){
return name;
}


public void setName(String name){
this.name = name;
}
}








3.UserDao.java


@Component
public class UserDao{


private SessionFactory sessionFactory;
public SessionFactory getSessionFactory(){
return sessionFactory;
}

@Resource
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}


public void add(User user){
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
session.close();
}


}




4.导入hibernate关于annotation的三个jar包
  ejb3-persistence.jar  hibernate-annotations.jar   hibernate-commons-annotations.jar




5.在com.bjsxt.po下建立一个User.java
@Entity
@Table(name="t_user")
public class User{
@Id
@GeneratedValue
private Integer id;
private String name;
private String phone;
private Integer age;

public User(String name,String phone,Integer age){
super();
this.name = name;
this.phone = phone;
this.age = age;
}

public User(){
super();
}

public Integer getId(){
return id;
}

public void setId(Integer id){
this.id = id
}

public String getName(){
return name;
}

public void setName(String name){
this.name = name
}

public String getPhone(){
return phone;
}

public void setPhone(String phone){
this.phone = phone;
}

public Integer getAge(){
return age;
}

public void setAge(Integer age){
this.age = age;
}
}






6.Test.java
public class Test{
public static void main(String[] args){
ApplicationContext ac = new ClassPathXmlApplicationContext(
new String[]{"applicationContext.xml"}
);
UserAction userAction = (UserAction)ac.getBean("userAction");
System.out.println(userAction.getClass().getName());
userAction.setName("xiaogao");
userAction.findByCondition();
}
}






7.运行项目,会生成一个表,然后访问http://localhost:8080/项目名/userAction!add?user.name=xiaogao则会添加数据到数据库




—————annotationg整合end—————————————





数据库连接池



怎样在我们的项目中用连接池及dataSource start————————————————


数据库连接池,一个班有50个人,不至于一个厕所得有50个坑吧。。小高这比喻。。。数据库崩溃了不是所有用户都不能访问了,而是几个用户不能访问了。就像买火车票,有的人买到


了,有的人没买到。




数据库连接池就是,提供你一定数量的连接,大家都从里面拿数据,当所有连接都被占用时,再进来的请求在连接
池外面排成队列等待。这样的好处是没有连接的时候不会去冒然创建连接导致报错,而是等待。有时候我们访问网站,会出现圈圈等待,那就是稀有资源被占用,过一会就好了,因为资


源被释放,你可以用这资源了。




数据库连接池的作用:1.稳定 2.提高性能(其实更多的是用户的体验高了,服务器本身并没有减轻负担,因为需要维护这个连池,而用户方面,它进到连接池后就直接可以拿到连


接,就好比去饭店吃饭,你进去后就直接有做好的,不用再等着现做了,快不快?)






实例


1.找到spring-framework-2.5.6\lib\jakarta-commons\下有两个包是必须的:commons-dbcp.jar和common-pool.jar(如果有c3p0,拷贝c3p0一个包就够了),把这两个包拷贝到项目下。




2.在applicationContext.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"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context   
http://www.springframework.org/schema/context/spring-context-2.5.xsd
"> 

   <context:component-scan base-package="com.bjsxt"></context:component-scan>

   <bean id="dataSource"  
            class="org.apache.commons.dbcp.BasicDataSource">  
            <property name="driverClassName"  
                value="com.mysql.jdbc.Driver">  
            </property>  
            <property name="url" value="jdbc:mysql://localhost:3306/test"></property>  
            <property name="username" value="root"></property>  
            <property name="password" value="1234"></property>
            <property name="maxIdle" value="15"></property>   //连接池内的连接数量
    </bean>  

   <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="packagesToScan">
   <list>
<value>com.bjsxt.po</value>
   </list>
</property>

<property name="dataSource" ref="dataSource"></property>

<property name="hibernateProperties">   //有数据库连接池了这里就不用再创建连接了。
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto"  >update</prop>
</props>
</property>
    </bean>

    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
    </bean>


    <tx:annotation-driven transaction-manager="txManager" /> 


</beans>








3.Test.java
public static void main(String[] args){
final ApplicationContext ac = new ClassPathXmlApplicationContext(
new String[]{"applicationContext.xml"}
);

//尝试短时间内,多次sql请求
for(int i=0;i<1000;i++){
new Thread(new Runnable(){
public void run(){
  UserDao dao = (UserDao) ac.getBean("userDao");
  User user = new User("xiaogao","123",12);
  dao.add(user);
}
}).start();
}
}






4.UserDao.java

@Component
public class UserDao {

private SessionFactory  sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Resource
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}

public  void add(User  user){
Session  session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
session.close();
}
}




5.运行Test.java



做内网项目,用户也就200来人的,最高峰值也就10、20,用不到池,互联网公司会用到,人人网、门户网站,并发量大的。
——————加数据库连接池end——————————————









——————HibernateTemplate详解、分页——————————————————
HibernateTemplate常见方法


用HibernateTemplate实现分页
  1.不用dao层,直接写service层,建个com.bjsxt.service包,下面写UserService接口,内容如下 
public interface UserService{
void add(User user);
void find4page(Integer pagenum,Integer pagesize);
}






  2.建个com.bjsxt.service.impl包,下面写UserServiceImpl类
@Component
public class UserServiceImpl implements UserService{

private HibernateTemplate hibernateTemplate;//Dao被HibernateTemplate取代了,所以service直接调用HibernateTemplate

public HibernateTemplate getHibernateTemplate(){
return hibernateTemplate;
}

@Resource
public void setHibernateTemplate(HibernateTemplate hibernateTemplate){
this.hibernateTemplate = hibernateTemplate;
}

public void add(User user){
hibernateTemplate.save(user);
}

//分页用的是hibernateTemplate的回调函数
public void find4page(final Integer pagenum,final Integer pagesize){  

List<User> list=(List<User>) hibernateTemplate.execute(new HibernateCallback(){
public Object doInHibernate(Session session) throws HibernateException,
SQLException{
Query query = session.createQuery("from User");
 query.setFirstResult((pagenum-1)*pagesize);
 query.setMaxResults(pagesize);
 return query.list();
}
});
}
}


   


封装的目的,不变的保留,变的通过参数传入。


3.希望能运行出来。。。讲的太乱了,这一句,那一句的,使用还没讲明白呢又去讲原理。0033零零散散。


———————HibernateTemplate分页end———————————————————————









—————————————事务—————————————————————————————


annotation方式开启事务
只要给我们的类前面加一个annotation的注解:transaction,我们的方法就具备了事务。说白了事务就是begintransaction和comminttransaction。这两行代码在方法前后执行,就构成了一个事务的严格的边界。


事务********
begin transaction可以开始一个事务,commit transaction可以提交这个事务。如果在此次执行中有错误,或想取消,可以使用RollbackTrans回滚事务,则在开始事务后的操作会被全部取消。 begin transaction的后面必须带commit transaction或 rollback transaction其中的一个
**************


但这种方法的问题是,想要一个事务,就需要在这个方法前加一个@Transactional。service层有很多的方法,action层也有很多的方法。每个头上都加很别扭。基本上有一个约定的规则:把事务的边界定义到service层。(action负责C,传递信息和跳转,所以不要在action层处理过多的逻辑,所以不要把@Transaction写在action层。)。用切面的形式在service层做事务管理。


具体实例:
1.在applicationContext.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"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context   
http://www.springframework.org/schema/context/spring-context-2.5.xsd
"> 

<context:component-scan base-package="com.bjsxt"></context:component-scan>

<bean id="dataSource"  
            class="org.apache.commons.dbcp.BasicDataSource">  
            <property name="driverClassName"  
                value="com.mysql.jdbc.Driver">  
            </property>  
            <property name="url" value="jdbc:mysql://localhost:3306/test"></property>  
            <property name="username" value="root"></property>  
            <property name="password" value="1234"></property>
            <property name="maxIdle" value="15"></property>
            <!-- 
            maxActive
minIdle 
maxIdle 
initialSize 
             -->
    </bean>  

<bean  id="sessionFactory"  class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >
<property name="packagesToScan" >
<list>
<value>com.bjsxt.po</value>
</list>
</property>

<property name="dataSource" ref="dataSource"></property>

<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto"  >update</prop>
</props>
</property>
</bean>


<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" >
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<!-- 
txManager 管理   事务的开启  和关闭
-->

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" >    //这里的ID是提供给下面的transaction-manager事务管理器的
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 
annotation  方式的 事务 也是 使用 代理模式。 
在需要事务的方法前后执行代码。    类似around 通知类型
-->

<tx:annotation-driven transaction-manager="txManager" /> 


<aop:config>
<aop:pointcut expression="execution(public * com.bjsxt.service.impl.*.*(..))" id="bussinessService"  />//这个切面的含义是切割所有service的实现类!!!!!!!!***********切面影响的是一个层。
<aop:advisor advice-ref="txAdvice" pointcut-ref="bussinessService" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="txManager" > //transaction-manager是事务管理器,必须要拿过来
<tx:attributes>
<tx:method name="find*" read-only="true" propagation="NOT_SUPPORTED" />   //对方法进行分类,需要事务的和不需要事务的方法分开,这里定义的是一个规则,以find开头的,设置为只读模式read-only="true",不需要事务propagation="NOT_SUPPORTED"
<tx:method name="add*" propagation="REQUIRED" />  //以add开头的方法需要事务 方法的定义一定要按规则,不解会切不到。在公司工作中,如果要添加方法,先要看人家之前这里怎么定义的,要按人家的规则走。
<tx:method name="del*" propagation="REQUIRED" />  //以del开头的方法需要事务
<tx:method name="update*" propagation="REQUIRED" />  //以update开头的方法需要事务
</tx:attributes>
</tx:advice>
</beans>


配置好了这个后,即使我们的方法不加@Transaction,方法也可以正确执行。因为这些方法已经默认有事务了。


——————————————题外
拿到一个项目,先看web.xml,配置了哪些filter,因为filter和servlet它们拦截的经常是/*,所以先看一下,你的请求会被哪些关键的过滤器拦截。接着再看AOP(applicationContext.xml),看看你的类会被哪些切面切到。这些都是对你的代码有深层影响的东西。别一上来就增删查改就写。




2.第一步是已经切面了,切完后做什么。。。tx是切面的简写
——————————————————————————————————————



2.Test.java
public class Test{
public static void main(String[] args){
ApplicationContext ac = new ClassPathXmlApplicationContext(
new String[]{"applicationContext.xml"}
);

//怎么看一个方法有没有事务=看它有没有代理类
UserService service = (UserService)ac.getBean("userServiceImpl"); //配置文件中没有写bean,但是我们在userServiceImpl前加@Component了。如果我们获取出来的类不是代理类,它前后没有植入功能,它的前面和后面就不会切到
System.out.println(service.getClass().getName());   //运行此方法,结果是$Proxy11,这是代理类的格式,说明是代理类。如果打印出来的是原生态的Name,那说明不是代理类。
User user = new User();
user.setName("123123123");
service.add(user);  //在上面那行确认了service类已经切到了,可以开始执行service的add方法了。
}
}




3.UserService.java
public interface UserService {

void add(User user);

void find4page(Integer pagenum, Integer pagesize);

}






4.UserServiceImpl.java
@Component
public class UserServiceImpl  implements UserService {

private HibernateTemplate  hibernateTemplate;
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
@Resource
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}

public void add(User user) {
hibernateTemplate.save(user);
}
public void find4page(final  Integer pagenum, final Integer pagesize) {
// java 设计者:   内外一致性
List<User>  list =(List<User>) hibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException,
SQLException {
// TODO Auto-generated method stub
Query  query =session.createQuery("from User");
query.setFirstResult((pagenum-1)*pagesize);
query.setMaxResults(pagesize);
return query.list();
}
});
// 模板方法模式       重用代码  
}
}






5.运行Test.java测试




———线程安全(冲突)解决方案 start———————————————————


1.ThreadLocal是为了解决线程并发。


线程安全问题:多个线程访问同样一个数据,这是线程安全的前提,两个人去抢一个东西,才会造成冲突。线程不安全的前提是:并发!

什么地方线程不安全呢?servlet(单例多线程),一个实例支撑多个线程对它的方法的调用。如果使用servlet的成员变量来存储值,那么这个场景会触发线程冲突。因为单例是单份的数据块,你一个线程对它进行删除,另一个线程又对它进行添加,再来一个线程对它进行修改。当线程过多的时候 ,数据肯定会错乱。冲突的后果是:脏数据。数据变得不稳定、不规律(本来数据应该从1变到2,结果还是1)冲突的原因是单例多线程。冲突的前提是:并发!解决冲突的思路是:ThreadLocal,它的解决办法是每一个线程一个数据块,大家不挣不抢。我们经常叫ThreadLocal线程局部变量。为当前线程绑定一个数据块(一个线程有一个小‘仓库数据块’来存储相应的值),从而解决线程冲突(三个小孩,一人一个苹果,还打架吗?)。
但是ThreadLocal解决冲突是有成本的,是一种空间换时间的思路。利用多余的空间换来了不冲突。本来1000个线程一个数据,这1000个线程得排队,现在是1000个线程,1000个数据块,不用排队,用户体验好了,但是空间占用多了。这种方式是空间换时间。






2.还有一种解决冲突的办法:锁!synchronized锁住以后,只有一个线程能进入到当前方法。剩下的线程都在排队。每次只一个线程进来,这样的话有很多线程在排队。这种方式是用时间换空间。




两种方案视情况,不同的需要选用不同的方案,如果内存小就空间优先,如果对时间有要求,就时间优先。




线程安全(冲突)解决方案end ————————————————






—————用ThreadLocal模式管理session—————————
ThreadLocal是一个线程绑定一个数据块。用它来管理Session是指为一个线程绑定一个Session对象,统一用这个Session对象。下一个线程也有自己的Session,每个Session都有自己的对象,因为不会造成冲突。一个线程绑定了一个Session对象后,在这个线程的任何一个地方,都可以把这个Session拿出来。所以括大了Session的生命周期。使用ThrealLocal管理Session对象后扩大了Session的生命周期。造成了一个结果就是Session不需要在一个方法内定义或是关闭了。因为我们可以把它放在一个线程里,让它在整个线程里有效。让这个Session不至于只在一个方法内有效。


一个线程可以调用很多个方法(有多个连接点),方法调用相互之间传参数、返回值。两个方法都需要创建Session,那么这个线程就可以和一个Session对象绑定,从而这些方法使用一个Session。



为什么要扩大Session生命周期?它能解决什么问题?
在hibernate中,1+N问题(一条SQL语句带来多条SQL语句执行),产生这个问题的原因是lazy="false",不懒加载,立即加载。解决1+N问题的办法是:把lazy="true"。但是lazy="true"以后,页面上使用代理对象的时候发现Session已经闭关了。所以这时候引出了扩大Session生命周期问题。


那怎么扩大呢?什么时候定义Session、关闭Session?最终引出了使用ThreadLocal来管理Session。


结论:1+N问题用ThreadLocal解决,也解决了1+N带来的所有问题





如果让我们自己来实现ThreadLocal怎么实现呢?


1.建立一个包com.bjsxt.filter,在它下面建立OpenSessionInViewFilter.java
public class OpenSessionInViewFilter implements Filter{

public void destroy(){
}

public void doFilter(ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException,ServletException{
Session session = sessionFactory.openSession(); //这定义的Session别人是不能用的,因为是局部变量。但是如果借助ThreadLocal就可以让别的方法也能使用此
Session。

HibUtil.threadLocal.set(session);  //这步置关重要!是把创建的session放到HibUtil的的threadLocal中。
arg2.doFilter(arg0,arg1); //此时Session扩大到请求和响应,从一个请求来服务器开始,到响应返回以后。后台执行的所有流程都是在Session生命周期内。
HibUtil.threadLocal.remove();
session.close();
}
public void init(FilterConfig arg0) throws ServletException{
}

}




2.定义一个util包,下面定义一个类HibUtil.java(借助ThreadLocal让Session生命周期变长)
public class HibUtil{

public static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();

public static Session getSession(){
Session session = threadLocal.get();
if(session == null){
session = sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}


public static void main(String[] args){
HibUtil.getSession();
HibUtil.getSession();  //一个线程中获取两次session,这两个拿出来的是一个Session,都是绑定在线程中的那个session,而且这个Session什么时候关不需要管
}
}




3.运行HibUtil.java测试








——————和自己写ThreadLocal管理Session作用相同的:Spring的OpenSessionInviewFilter的用法————————————


**OpenSessionInviewFilter是spring提供的一个针对Hibernate的支持类,和我们上面写的代码的作用一样。主要意思是在发起一个页面请求时打开Hibernate的Session,一直保持这个Session,直到这个请求结束,具体是通过一个Filter来实现的************


1.把如下代码配置到struts过滤器之前
<!--配置Spring自动管理Session,要配置到struts过滤器之前-->
<filter>
<filter-name>hibernateSessionFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInviewFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>hibernateSessionFilter</filter-name>
<url-pattern>*.action</url-pattern>   //最好改成*.action,只拦截action,只拦截对后台发起的访问,在这个时候打开session是有必要的。如果只是访问html就打开一Session会造成浪费,这样的配置会浪费性能。
</filter-mapping>


**使用spring的hibernateSessionFilter,就把session的生命周期放在了filter位置,把事务开和关放在了service层









********题外,以后的环境模型架子*********************************
applicationContext.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"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context   
http://www.springframework.org/schema/context/spring-context-2.5.xsd"> 

<context:component-scan base-package="com.bjsxt"></context:component-scan>

<bean id="dataSource"         //有连接池
            class="org.apache.commons.dbcp.BasicDataSource">  
            <property name="driverClassName"  
                value="com.mysql.jdbc.Driver">  
            </property>  
            <property name="url" value="jdbc:mysql://localhost:3306/test"></property>  
            <property name="username" value="root"></property>  
            <property name="password" value="1234"></property>
            <property name="maxIdle" value="15"></property>
</bean>  

<bean  id="sessionFactory"  class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >    //有sessionFactory

<property name="packagesToScan" >     //有sessionFactory中的包扫描器
<list>
<value>com.bjsxt.po</value>
</list>
</property>

<property name="dataSource" ref="dataSource"></property>

<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto"  >update</prop>
</props>
</property>
</bean>

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" >   //有HibernateTemplate
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" >   //有事务
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<tx:annotation-driven transaction-manager="txManager" />     //annotation式的事务



<aop:config>    //AOP
<aop:pointcut expression="execution(public * com.bjsxt.service.impl.*.*(..))" id="bussinessService" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="bussinessService" />
</aop:config>


<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="find*" read-only="true" propagation="NOT_SUPPORTED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" /> 
</tx:attributes>
</tx:advice>
</beans>




这个applicationContext.xml配置文件写好后就不需要修改了,只有以下几点需要注意


再添加配置就是添加struts2.xml中的action,或spring的bean的annotation配置(不需要改配置文件) ,hibernate的entity(po)不需要改配置文件




在拿到项目后,也要先看看,首先看数据库连接和本机一样否,aop的切面是否和你的包结构一样。仔细审查配置文件的功能是否符合当前项目。


struts使用配置文件的好处是能看清谁往哪跳,逻辑比较一目了然。spring和hibernate使用annotation,只把固定的写在applicationContext.xml中。
************************************************************************************






题外————
在依赖注入时,当属性是集合类型时,如何注入值??(如action中的属性是数组类型,String[],在applicationContext.xml中怎么配置才能注入值呢?)


代码实例
1.UserDao.java代码如下
public class UserDao{
private String[] ccc;
public String[] getCcc(){
return ccc;
}

public void setCcc(String[] ccc){
this.ccc = ccc;
}

public List<String> list;

private Set<String> set;
private Map<String, String> map;
private Properties pp;

/**
...这些属性的set、get方法
**/

public UserDao(){
System.out.println("init......");
}

public void add(){
System.out.println("add......");
}
}




2.applicationContext.xml代码如下
<bean id="userDao" class="com.bjsxt.dao.UserDao">
<property name="ccc">    //这样就赋与了cc这个数组属性三个值,每个property对应了bean的class中的类的一个属性
<list>
<value>111</value>
<value>222</value>
<value>333</value>
</list>
</property>
<property name="list">
<list>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</list>
</property>
<property name="set">
<set>
<value>sss</value>
<value>qqq</value>
<value>www</value>
</set>
</property>
<property name="map">
<map>
<entry>
<key><value>name</value></key>
<value>xiaogao</value>
</entry>
</map>
</property>
<property name="pp">
<props>
<prop key="cacheProvider">ehcache</prop>  //ehcache是随便写的字符串,给pp赋的值
</props>
</property>
</bean>






3.加一个main方法来测试
public class Test{
public static void main(String[] args){
ApplicationContext ac = new ClassPathXmlApplicationContext(
new String[]{"applicationContext.xml"}
);

UserDao dao = (UserDao) ac.getBean("userDao");
dao.add();
}
}




4.在dao.add()上打断点进行debug调试


题外end——————————————————————————————————

SPRING END——————————————————————————————

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值