SSH框架零配置搭建

依然沿用第一篇文章里的项目:SSH框架入门搭建

步骤分析
逐步代替掉各种xml配置文件中的配置
  1. 使用注解替代数据库表映射类的配置文件
  2. 使用注解替代Spring中的业务逻辑的bean标签
  3. 使用注解事务代替声明式事务
  4. 使用注解替代struts.xml配置文件
  5. 使用注解替代Spring配置文件ApplicationContext.xml
开始
1.替代数据库表映射类的配置文件

Hibernate拥有良好的JPA实现,所以能直接使用JPA注解来映射java实体类和数据库表,
所以注解依赖于HIbernate-jpa.jar这个jar包,这个jar包在hibernate3开始hibernate官方的一套jar包中已经附带了这个jar包,我们这里使用的hibernate5所以不需要再额外增加
在这里插入图片描述
emp表

package org.hua.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
 * @author iasyyyyy
 * @Entity标签标注在一个数据库表映射类上边,表明这是一个数据库表的映射实体类
 * @Table标签的name属性指定数据库中本表所对应的表名,如果映射类类名和数据库表名一样则可以省略
 * 
 */
@Entity
@Table(name="EMP")
public class Emp {
	/**
	 * @id指被标注的属性为数据库表的主键,在hbm映射配置文件中我们知道,id列必须有generator属性来指定主键的生成策略
	 * 	在这里则需要使用@GeneratedValue标签指定本主键的生成策略,strategy属性指定生成策略
	 * 	strategy属性的值可以使用GenerationType的枚举类型,以下是常用的几种
	 * GenerationType.IDENTITY   指定主键由数据库进行自增,适合支持自动增长的数据库如MySql,SqlServer
	 * GenerationType.AUTO   由程序来控制主键的生成,自动适应数据库,但是在高并发和集群环境下慎用
	 * GenerationType.SEQUENCE   采用数据库提供的sequence机制生成主键,需要数据库支持sequence。如oralce
	 * 
	 * @columu标签指定属性在数据库表中所映射的列,name指定列名,如果属性名跟数据库中的的列名一致则可以省略
	 * 	 
	 * 	这些注解标签可以标在属性上边也可以标在属性的get或set方法上,这里我们标在属性名上
	 */
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="EID")
	private Integer eId;
	
	@Column(name="ENAME")
	private String eName;
	
	@Column(name="EPSD")
	private String ePsd;
	
	@Column(name="EREALNAME")
	private String eRealName;
	
	@Column(name="ESEX")
	private Integer eSex;
	
	@Column(name="EAGE")
	private Integer eAge;
	/**
	 * @ManyToOne配置多对一关系,标注在多方中持有的一方对象的上
	 * @JoinColumn指定关联两张表所关联的列
	 */
	@ManyToOne
	@JoinColumn(name="DID")
	private Dept dept;
		
	//getter,setter方法省略
}

dept表

package org.hua.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="DEPT")
public class Dept {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="DID")
	private Integer dId;
	
	@Column(name="DNAME")
	private String dName;
	
	@Column(name="SESCRIPTION")
	private String description;
	/**
	 * @OneToMany配置一对多关系,标注在一方所持有的多方的集合上
	 * @JionColumn指定关联的列
	 */
	@OneToMany
	@JoinColumn(name="DID")
	private Set<Emp> empSet=new HashSet<>();

	//getter,setter方法省略
}

配置完数据库和实体类的映射关系之后我们需要在配置文件中指定这个映射的实体类,
删除掉applicationContext.xml中sessionFatory的mappingResources这个peoperties,因为我们既然已经在类上注解配置映射类就已经不需要再指定映射的配置文件,但是需要指定映射类

	<!-- 如果使用注解标注表映射实体类就需要指定实体类所在的包进行扫描自动进行映射 -->
	<property name="packagesToScan" value="org.hua.entity"></property>

在sessionFactory中配置packagesToScan标签扫描给出的包路径,扫描路径下带有注解的实体类,然后就可以直接把两个hbm.xml文件删了

2.替代Spring中的业务逻辑的bean标签

首先需要在applicationContext.xml中开启包扫描

	<!-- 开启包扫描,会扫描给出包路径下的所有标注有@component,@Repository,@Service,@Controller 
		等注解标注的类并自动放入Ioc容器中 -->
	<context:component-scan base-package="org.hua"></context:component-scan>

@Repository标签标注的类指定是DAO层
@Service标签标注的类指定是Service层
@Controller标签标注的类指定是Controller层

然后就在三层的业务逻辑中直接在业务的实现类上标注各类所代表的各业务逻辑层,然后在类中需要注入的属性上标上标签让Ioc容器自动注入
DAO层

/**
 * @Repository指定所标注的类是DAO层并自动放入Ioc容器如果不指定value值则默认使用类名的首字母大写为bean的id
 *	value属性则而可以设置bean的id值
 */
@Repository("empDao")
public class EmpDaoImpl implements EmpDao {
	/**
	 * @Autowired标签标注在属性上表示属性自动装配,默认是ByType方式,	就是根据声明的数据的类型在Ioc容器中
	 * 	寻找相匹配的类型进行自动注入,这种方法如果本种类型的bean在Ioc容器中有多个bean那就会报出异常,如果
	 * 配合@Qualifier标签使用就可以是自动装配的类型转换为ByName,
	 * 在@Qualifier标签直接传入需要的bean的id可以根据bean的id装配
	 */
	@Autowired
	@Qualifier("sessionFactory")
	private SessionFactory sessionFactory;
	
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

Service层

@Service("empService")
public class EmpServiceImpl implements EmpService {
	
	@Autowired
	@Qualifier("empDao")
	private EmpDaoImpl edi;
	

Controller层

@Controller
@Scope("prototype")
public class EmpAction extends ActionSupport {

	@Autowired
	@Qualifier("empService")
	private EmpServiceImpl esi;
	private Integer id;
	private String name;
	private String psd;
	private List<Emp> list;

到这就可以把applicationContext.xml中配置的三层业务逻辑的bean删除了

3.注解事务

在application中开启注解事务的支持

	<!-- hibernate的事务管理器 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
	
	<!-- 开启注解事务 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>

然后我们就可以在需要开启事务的业务逻辑上使用@Transactional注解标注事务,因为Service层有可能调用多个DAO层的方法,所以我们一般在Service层声明事务

	/**
	 * @Transactional标签如果标注在方法上被标注的方法则以事务的方式执行
	 * 	如果标注在类名上则本类所有方法全部以事务的方式执行
	 * 	有多个属性如readOnly:指定事务是不是只读事务,如果是,那本方法只能进行查询操作不能进行增删改
	 * 	如登录,全查,单查等方法就是只读事务,如果不指定readOnly属性则默认为false
	 */
	@Transactional(readOnly=true)
	public Emp empLogin(String name, String psd) {
		
		return edi.empLogin(name, psd);
	}

	@Transactional(readOnly=true)
	public List<Emp> empQueryAll() {
		// TODO Auto-generated method stub
		return edi.empQueryAll();
	}
4.使用注解替代struts.xml配置文件

就是去掉struts.xml文件,直接在Action类的方法上边定义Action和跳转路径等
需要依赖到一个Struts2的注解jar包,struts-covention-plugin.jar

在这里插入图片描述
并且有一个默认规则:
如果使用注解定义Action,那么注解Action所在的类报名必须为action,必须继承Action’Support类
然后就在我们的Controller层也就是Action类上边加上注解@parentPackage指定继承的包,默认为struts-default
@Namespace指定包命名空间

@Controller
@ParentPackage("struts-default")
@Scope("prototype")
@Namespace("/")
public class EmpAction extends ActionSupport {

然后在相应的Action需要跳转的方法名上边直接加上@Action注解,加完注解Controller层就是这样

	package org.hua.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.hua.entity.Emp;
import org.hua.service.impl.EmpServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.google.gson.Gson;
import com.opensymphony.xwork2.ActionSupport;

@Controller
@ParentPackage("struts-default")
@Scope("prototype")
public class EmpAction extends ActionSupport {

	@Autowired
	@Qualifier("empService")
	private EmpServiceImpl esi;
	private Integer id;
	private String name;
	private String psd;
	private List<Emp> list;
	
	//getter,setter方法省略
	
	/**
	 * @Action指定标注的方法为一个Action,也可以标注在类名上,value指定Action名
	 *  results需要放一个@result数值,指定返回参数的不同去到不同的页面或Action
	 *  @result的name就是指定返回的参数,location指定返回的页面或Action
	 * 
	 */
	@Action(value="loginAction",results= {
			@Result(name="success",location="/empShow.jsp"),
			@Result(name="input",location="/index.jsp")
	})
	public String empLogin() {
		Emp emp = esi.empLogin(name, psd);
		if(emp!=null) {
			list=esi.empQueryAll();
			
			return SUCCESS;
		}
		
		return INPUT;
	}
}

到这,基本已经完成了SSH框架的注解开发,但是,既然是0配置,就是不需要一个xml包括Spring的applicationContext.xml,下面我们来干掉applicationContext.xml

替代Spring配置文件ApplicationContext.xml

首先我们要知道applicationContext.xml是spring的核心配置文件,包括他对hibernate的控制等配置文件都在这个文件中,若果去掉这个配置文件那这些配置我们怎么配置呢?
一般我们写一些测试类等在main方法中先声明一个ClassPathXmlApplicationContext对象,他是applicationContext的实现类之一,传入配置的applicationContext.xml路径就可以初始化Ioc容器。在Spring3.0以后官方又引入了ApplicationContext的两个新的实现类AnnotationConfigApplicationContext和AnnotationConfigWebApplicationContext这两个实现类分别是Spring注解开发的应用上下文对象,对Spring的注解开发提供了支持。同时还引入了一些关于Spring配置类的注解开发相关的注解标签,下面我们就开始使用注解逐步替代掉applicationContext.xml。
虽然是0配置,但其实只是去掉了xml配置文件,换成了使用java类来进行配置,所以首先需要声明一个普通的java类,然后直接在了类名上加上注解@Configuration注解标注这是一个Spring配置类

注意:@Configuration注解的配置类有如下要求:
  • @Configuration不可以是final类型;
  • @Configuration不可以是匿名类;
  • 嵌套的configuration必须是静态类。

然后类在声明各个bean,bean使用方法来代替要声明哪一个类的bean就直接在类中定义一个返回值类型为需要配置的bean的类型,方法名任意的方法,bean如果有依赖则使用方法的传入参数来传入
例如需要创建一个DAO的bean在applicationContext.xml配置文件中这样写

	<bean id="empDao" class="org.hua.dao.impl.EmpDaoImpl">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>

在类中就这样写

	/**
	 * @Bean标注所标注的方法是需要自动放入Ioc容器的一个Bean,name属性指定bean的id如果不指定name属性
	 * 	则bean的id默认为方法名
	 * 	传入参数的参数名如果依赖的其他bean则名字需要跟所依赖的beanid相同
	 */
	@Bean(name="empDao")
	public EmpDaoImpl empDao() {
		return new EmpDaoImpl();
	}

如果有依赖的其他bean就这样写

	@Bean(name="empDao")
	public EmpDaoImpl empDao(SessionFactory sessionFactory) {
		EmpDaoImpl edi=new EmpDaoImpl();
		edi.setSessionFactory(sessionFactory);
		return edi;
	}

如此就可以创建bean,但是由于我们是在各层业务的类名上边注解注入的Ioc容器所以dao层我们不需要在手动声明bean,但是也需要开启包扫描在类名上再加上@ComponentScan注解并传入需要扫描的包名

@Configuration
@ComponentScan(basePackages="org.hua")//这句话就相当于<context:component-scan base-package="org.hua"></context:component-scan>
public class ConfigrationManager {

然后就开始配置hibernate相关
首先是数据库连接池数据源

	@Bean(name="dataSource")
	public ComboPooledDataSource dataSource() {
		ComboPooledDataSource cpds=new ComboPooledDataSource();
		try {
			cpds.setDriverClass("com.mysql.jdbc.Driver");
			cpds.setJdbcUrl("jdbc:mysql:///test");
			cpds.setUser("root");
			cpds.setPassword("123456");
		} catch (PropertyVetoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return cpds;
	}

然后是sessionFactory

	@Bean(name="sessionFactory")
	public LocalSessionFactoryBean sessionFactory(ComboPooledDataSource dataSource) {
		
		LocalSessionFactoryBean sessionFactory=new LocalSessionFactoryBean();
		sessionFactory.setDataSource(dataSource);
		//扫描给出包下的注解的数据库映射类
		sessionFactory.setPackagesToScan("org.hua.entity");
		//Hibernate的各项配置
		Properties pro=new Properties();
		//数据库方言
		pro.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
		//显示Sql语句
		pro.setProperty("hibernate.show_sql","true");
		pro.setProperty("hibernate.format_sql","true");
		sessionFactory.setHibernateProperties(pro);
		
		return sessionFactory;
	}

然后开启注解事务,再在类名上加注解@EnableTransactionManagement,开启注解事务支持
由于我们的DAO和Service都实现了接口所以需要开启配置属性proxyTargetClass=true,否则会报出类型不匹配异常

@Configuration
@ComponentScan(basePackages="org.hua")
@EnableTransactionManagement(proxyTargetClass=true)
public class ConfigrationManager {

然后需要添加事务管理器的bean

	@Bean
	public HibernateTransactionManager txManager(SessionFactory sessionFactory) {
		
		return new HibernateTransactionManager(sessionFactory);
	}

最后是web.xml文件的配置
原来在web.xml中Spring的配置是这样

<!-- 如果是使用注解类进行spring的配置就需要先指定spring配置文件的加载类并指定路径 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	<!-- spring启动监听器 -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

但是我们现在是注解配置的Spring所以这个配置已经不能使用,上边说Spring3.0引入的两个新的实现类AnnotationConfigApplicationContext和AnnotationConfigWebApplicationContext,其中AnnotationConfigWebApplicationContext就是用于对于web开发支持的类,所以我们需要把web.xml配置文件改成这样

	<!-- 如果是使用注解类进行spring的配置就需要先指定spring配置文件的加载类并指定路径 -->
	<context-param>
		<param-name>contextClass</param-name>
		<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
	</context-param>
	
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>org.hua.test.ConfigrationManager</param-value>
	</context-param>
	<!-- spring启动监听器 -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

如此就完成了SSH框架的0配置整合

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值