基于注解的SSH架构整合之二

1   整合Struts2

     完成了SpringHibernate的整合,最后一步我们将对Struts2Spring进行整合。编写一个struts.xml的文件,该文件存放在src目录下。

      配置由Spring实例化Struts2,需要Spring框架的支持

<constant name="struts.objectFactory" value="spring"></constant> 

      

     配置国际化编码

<constant name="struts.i18n.encoding" value="UTF-8"></constant>


     配置convention-plugin注解插件,要让Struts2支持注解,这一步是必须的!

<constant name="struts.convention.default.parent.package" value="default" />

    

     完整配置如下

<?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
	"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
  <constant name="struts.enable.DynamicMethodInvocation" value="false" />
   <constant name="struts.devMode" value="false" />
   <constant name="struts.objectFactory" value="spring"></constant>
	<!--charset-->
   <constant name="struts.i18n.encoding" value="UTF-8"></constant>
   <!-- convention-plugin  -->
   <constant name="struts.convention.default.parent.package" value="default" />
   <package name="default" extends="struts-default,json-default">
      <interceptors>
      	 <interceptor-stack name="securedStack">
      	 	 <interceptor-ref name="defaultStack" />
      	 </interceptor-stack>
      </interceptors>
      <default-interceptor-ref name="securedStack"></default-interceptor-ref>
      <global-results>
			<result name="error">/error.jsp</result>
			<result name="invalid.token">/error.jsp</result>
			<result name="login" type="redirect">/login</result>
	</global-results>
   </package>
</struts>


 

       在web.xml中增加Struts2的过滤器,将Struts2集成到WEB工程中。

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>


 

2  增加日志文件配置

       前面我们已经完了SSH架构的整合,为了让程序更容易调试和跟踪问题,我们把log4j加上,以便排查项目开发中出现的各种异常。本配置使用了apacheslf4j框架,slf4j框架对log4j进行了集成,使log4j的使用更简单,slf4j是开源社区中非常火的框架。

   

log4j.debug=false

log4j.rootLogger=debug,Stdout

# please keep this setting FATAL to avoid questions from users
# why there are stacktraces in the test output. You can turn it
# down if you need to when testing, but don't check it in. (eelco)

# changing back to ERROR. Looks like in some cases the log4j.properties
# in wicket gets picked which results in not printing the exceptions
# and that can be a bit dangerous (matej)
log4j.logger.com.ssh=info
log4j.logger.DBstep=error
log4j.logger.org.hibernate=info
log4j.logger.org.apache.struts2=debug
log4j.logger.org.springframework=debug
log4j.logger.com.opensymphony=info
log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.Stdout.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n

3  如何使用注解

3.1    Spring注解

         Spring的注解有很多,我们只介绍在架构中常用到的注解,分别为@Resource@Autowired@Service@Repository@Component@Transactional六个注解。

       DI注解:

       @Resource其实不是Spring中的注解,而是JAVA中的标准注解,是JSR-250中的一个规范,Spring对其进行了实现。使用@Resource注解可以注入JavaBean,默认按照名字注入JavaBean

       

@Resource(name="personDao")
IPersonDao personDao;


 

          @AutowiredSpring的一个注解,作用和@Resource是一样的,@Autowired默认按照类型注入。

        IOC注解:

          @Service用来标注在Service类上,表示让Spring来实例化Service类,也就是我们所说的IOC

<span style="font-size:14px;">@Service //标注service层
public class PersonService implements IPersonService
</span>


        @Repository用来标注在DAO类或是数据访层的类中,作用和@Service一样。

@Repository //标注dao层
public class PersonDao extends GenericReposistoryHibernate implements   IPersonDao

 

            @Component用来标注普通的JavaBean,例如POJOMODEL类等。

@Component("personPojo" )// 把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>
public class PersonPojo extends GenericObject

 

         事务注解:

             @Transactional是事务注解,使用该注解可以让Spring代替我们接管事务,不用每次都由程序员来提交和回滚事务。

           

3.2    JPA与Hibernate注解

         之前讲到过Hibernate中使用注解用到的是JPAJPA其实也是JAVA中的规范之一,是与EJB3一起诞生的产物,全称为Java Persistence APIJAVA持久化API)。使用JPA可以实现Java BeanORM映射,包括对象和表、属性和字段、对象依赖和表间关系的映射(例如一对一、一对多、多对多的映射)。下面的示例是JPA的基本使用方法:

         

<span style="font-size:14px;">@Entity //标注该类为实体类。
@Table(name = "person") //标注对应的数据库表明。
@Component("personPojo" )// 把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>
public class PersonPojo extends GenericObject {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String name;

	@Column(name = "name", unique = true)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}
</span>


          

          GenericObject,该类提供一个父类的ID,所有继承该类的子类都具有一个ID

<span style="font-size:14px;">@MappedSuperclass
public abstract class GenericObject{
    private static final long serialVersionUID = 1L;
	private String id;
    public GenericObject() {
		super();
	}

	@Id
	@Column(name = "id", length = 36, nullable = true)
	@GeneratedValue(generator = "hibernate-uuid.hex")
	@GenericGenerator(name = "hibernate-uuid.hex", strategy = "uuid.hex")
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}
}
</span>


         使用<prop key="hibernate.hbm2ddl.auto">update</prop>属性可以使Hibernate自动创建和修改表,而不用再手工修改。

关于如何使用JPA,请参考我的另一篇博文JPAHibernate中的使用》。这篇文章详细介绍了JPA的语法和使用方法。

          

3.1    Struts2注解

          Struts2框架的注解是使用convention-plugin插件实现的,关于Struts2插件的使用请参考我的另一篇博文《在Struts2框架中使用注解》。

4  如何在工程中使用Spring切面事务和增删改查

      在使用JDBC或者是Hibernate对数据库的进行增删改查操作时,通常都需要使用事务。事务是保证数据一致性和完整性的重要技术,如果使用不当,可能会产生不完整的交易数据,所以在软件开发中对事务的控制一定要认真对待。Spring为我们提供了AOP切面事务,使程序员不用自行控制事务。使用Spring事务我们只需要标注@Transactional注解即可,Spring会自动接管方法中的事务。我们可以定一个数据库访问层的公共类,所有的DAO类都继承至该类,而不用在每个DAO都使用@Transactional注解。

      

/**
 * 持久化基类
 * 
 * @author 山人
 * 
 */
@Transactional
@Component("repositoryImp")
public class GenericReposistoryHibernate {
	@Resource
	protected SessionFactory sessionFactory;
	private Session session = null;

	@Transactional
	public <T, PK extends Serializable> PK create(T newInstance) {
		PK save = (PK) getSession().save(newInstance);
		return save;
	}

	@Transactional
	public <T> void delete(T transientObject) {
		getSession().delete(transientObject);
	}

	@Transactional
	public <T> void update(T transientObject) {
		getSession().update(transientObject);
	}

	@Transactional(readOnly=true)
	public <T> List<T> findAll(Class<T> type) {

		return getSession().createCriteria(type).list();
	}

	public <T> List<T> findHQLByParam(String hql, int firstResult,
			int maxResult, Object... params) {
		Query query = getSession().createQuery(hql);
		for (int i = 0; i < params.length; i++) {

			query.setParameter(i + 1, params[i]);
		}
		query.setMaxResults(maxResult);
		query.setFirstResult(firstResult);
		return query.list();

	}

	@Transactional(readOnly=true)
	public <T> List<T> findAllValid(Class<T> clas) {

		return getSession().createCriteria(clas).list();
	}

	@Transactional(readOnly=true)
	public <T, PK extends Serializable> T get(Class<T> type, PK id,
			boolean block) {
		if (block)
			return (T) getSession().get(type, id, LockMode.UPGRADE);
		else
			return (T) getSession().get(type, id);
	}

	public Session getSession() {
		if (sessionFactory.isClosed()) {
			sessionFactory.openSession();
		} else {
			session = sessionFactory.getCurrentSession();
		}
		return session;
	}
}


 

 

 

 

 

 

你可能感兴趣的:(注解,spring,Hibernate,struts2,ssh)