昆明java培训
达内昆明广州春城路

18487146383

热门课程

Java程序员:给你一个稳妥的后端解决方案

  • 时间:2016-10-21
  • 发布:昆明Java培训
  • 来源:达内新闻

昆明Java培训机构的老师今天给大家讲后端解决方案,大体采用的开源项目有:Spring + SpringMVC + Druid + JPA(Hibernate Impl)。

1.采用到的开源项目漫谈

Spring迷人的依赖注入特性,使其已经稳稳的占据在JavaEE项目引用开源项目列表中的上层位置。

秉承低耦合高内聚的遵旨,Spring提倡的对象工厂解耦类关系的思想已深入到每个攻城狮的心中。

SpringMVC做为Spring的干儿子,最让我沉醉的是她强大的扩展能力,深邃的像大海一样。

前端无论是freemarker/velocity/jsp...,后端DAO层无论是传统的ORM还是新近上位的领域模型。

她的态度始终如一,给你360度最贴心的呵护,有一人对你如此,此生足矣。

项目中关于SpringMVC + Spring的依赖:

<!--spring mvc-->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

<version>4.3.3.RELEASE</version>

</dependency>

<!-- Spring-orm -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-orm</artifactId>

<version>4.3.3.RELEASE</version>

</dependency>

<!-- Spring AOP动态代理-->

<dependency>

<groupId>org.aspectj</groupId>

<artifactId>aspectjweaver</artifactId>

<version>1.8.9</version>

</dependency>

这上面昆明Java培训机构的老师想说的是AspectJ这个东东,AspectJ是最早、功能比较强大的AOP实现之一。

在Java领域,AspectJ中的很多语法结构基本上已成为AOP领域的标准。

Spring也有自己的Spring-AOP,Spring-AOP采用运行时生成代理类,底层可以选用JDK或者CGLIB动态代理。

通俗点,AspectJ在编译时增强要切入的类,而Spring-AOP是在运行时通过代理类增强切入的类,效率和性能可想而知。

所以Spring在2.0的时候就已经开始支持AspectJ,现在到4.X的时代已经很完美的和AspectJ 结合到一起。

项目中的web.xml配置监控配置和监控界面:

<!--Druid数据库连接池监控-->

<servlet>

<servlet-name>DruidStatView</servlet-name>

<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>DruidStatView</servlet-name>

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

</servlet-mapping>

JPA作为Sun公司引入的ORM规范,就像是JDBC之于各种数据库驱动Jar,

不要去在意使用了什么样的数据库,用JDBC提供的规范方法去撸代码即可。

JPA制定持久层规范,相同与抽象接口,有ORM框架撸具体的实现层。

Sun想实现ORM技术统一,可能不远的将来,你不用在纠结选择什么样子的ORM框架。

而现有热门的ORM框架会渐渐失去光泽,这毕竟是个漫长的过程,让我们拭目以待。

2.方案整体一览

方案中所有的类都位于SpringContext中,由Spring统一进行管理。

让Spring统一管理的前提是你要告诉有这样一个类需要它管理,目前我接触到的告诉途径有两种。

传统的xml配置和注解方式,xml配置和注解方式各有优劣,比如xml配置的优点:

a.如果你公司项目在引用另外一个公司的jar,这时候,唯一可行方式为xml配置。

b.如果类之间的依赖关系变动频繁,xml配置是比较优秀的,改动代码和改动配置文件,无论是技术上还是风险上,xml都稳赢注解。

注解声明的方式优点:代码和声明在一起,开发的时候不用切来切去,比xml配置声明要简单明了的多。

现在很多主流的框架都引入了注解,但也无法摈弃xml配置声明的方式。

在这个方案中昆明Java培训机构的老师使用干净简单注解的方式,controller包下使用注解@controller,dao-impl包下使用@Repository,service包下使用@service。

控制层注入服务实例,服务层注入数据访问层对象,持久层对象由JAP进行注解,页面通过控制层来传输和获取数据。

web.xml:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

version="3.0">

<!--Spring mvc -->

<servlet>

<servlet-name>springMVC</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<init-param>

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

<param-value>

classpath:spring-mvc-base.xml

classpath:spring-mvc-beans.xml

classpath:spring-hibernate-beans.xml

</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

<async-supported>true</async-supported>

</servlet>

<servlet-mapping>

<servlet-name>springMVC</servlet-name>

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

</servlet-mapping>

<!--Druid数据库连接池监控-->

<servlet>

<servlet-name>DruidStatView</servlet-name>

<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>DruidStatView</servlet-name>

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

</servlet-mapping>

</web-app>

maven pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.rambo</groupId>

<artifactId>sdh</artifactId>

<packaging>war</packaging>

<version>1.0-SNAPSHOT</version>

<name>sdh</name>

<description>spring mvc + Druid + hibernate</description>

<dependencies>

<!--spring mvc-->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

<version>4.3.3.RELEASE</version>

</dependency>

<!-- Spring-orm -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-orm</artifactId>

<version>4.3.3.RELEASE</version>

</dependency>

<!-- Spring AOP动态代理-->

<dependency>

<groupId>org.aspectj</groupId>

<artifactId>aspectjweaver</artifactId>

<version>1.8.9</version>

</dependency>

<!-- Hibernate-core -->

<dependency>

<groupId>org.hibernate</groupId>

<artifactId>hibernate-core</artifactId>

<version>4.3.1.Final</version>

</dependency>

<!-- Druid -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid</artifactId>

<version>1.0.26</version>

</dependency>

<!--mysql数据驱动-->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>5.1.38</version>

</dependency>

<!--日志-->

<dependency>

<groupId>log4j</groupId>

<artifactId>log4j</artifactId>

<version>1.2.17</version><!--2012.05最后版本-->

</dependency>

</dependencies>

<build>

<finalName>sdh</finalName>

<plugins>

<plugin>

<groupId>org.eclipse.jetty</groupId>

<artifactId>jetty-maven-plugin</artifactId>

<version>9.2.11.v20150529</version>

<configuration>

<jvmArgs>-XX:PermSize=256M -XX:MaxPermSize=1024M</jvmArgs>

<webApp>

<contextPath>/${project.name}</contextPath>

</webApp>

<httpConnector>

<port>4040</port>

</httpConnector>

<stopKey>foo</stopKey>

<stopPort>9998</stopPort>

</configuration>

</plugin>

</plugins>

</build>

</project>

3. DAO层的种种设计思路

Controller和Service层非常容易理解,这里不赘述了。

DAO层中BasePo希望将一些共有的属性抽象在父类当中(属性由具体项目需求决定)。

@MappedSuperclass

public class BasePO implements Serializable {

@Id

@Column(length = 32, nullable = true)

@GeneratedValue(generator = "uuid")

@GenericGenerator(name = "uuid", strategy = "uuid")

private String uuid;

@Column(updatable = false)

private Date createDate;

private Date modifyDate;

....getter/setter

}

BaseDaoImpl希望将一些公共的数据访问方法实现在父类当中(我这里的方法可能有点少,可以由具体项目增加)。

@Repository

public class BaseDaoImpl<T, PK extends Serializable> implements BaseDao<T, PK> {

private Class<T> entityClass;

@Resource

protected SessionFactory sessionFactory;

public BaseDaoImpl() {

this.entityClass = null;

Class<?> c = getClass();

Type type = c.getGenericSuperclass(); //反射获取超类

if (type instanceof ParameterizedType) {

Type[] parameterizedType = ((ParameterizedType) type).getActualTypeArguments();

this.entityClass = (Class<T>) parameterizedType[0];

}

}

protected Session getSession() {

return sessionFactory.getCurrentSession();

}

public T getByKey(PK id) {

Assert.notNull(id, "id is required");

return (T) getSession().get(entityClass, id);

}

public T add(T entity) {

Assert.notNull(entity, "entity is required");

getSession().save(entity);

return entity;

}

public T edit(T entity) {

Assert.notNull(entity, "entity is required");

getSession().update(entity);

return entity;

}

public T deleteByKey(PK id) {

Assert.notNull(id, "id is required");

T t = (T) getSession().load(entityClass, id);

getSession().delete(t);

return t;

}

}

使用JAP注解编写业务使用到的持久层对象。

@Entity

@Table(name = "t_user")

public class User extends BasePO {

@Column(nullable = false)

String name;

@Column(nullable = false)

String pwd;

....getter/setter

}

配置启动时扫描POJO的动作,至于是新建还是更新都有配置选项,可以自己查阅相关文档。

<!--配置hibernate session工厂,需添加spring-orm -->

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

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

<property ame="hibernateProperties">

<props>

<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>

<prop key="hibernate.dialect">${hibernate.dialect}</prop>

<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>

<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>

</props>

</property>

<!--自动扫描注解方式配置的hibernate类文件-->

<property ame="packagesToScan">

<list>

<value>com.rambo.sdh.pojo</value>

</list>

</property>

</bean>

操纵数据库最主要的事务管理,采用AOP声明方式,在执行含有数据变动的方法前后进行拦截。

采用AOP声明方式进行拦截的好处,不用去关注数据库事务的开启和关闭,将重心放到业务逻辑上面。

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

<bean ame="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">

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

</bean>

<!--声明式容器事务管理,transaction-manager指定事务管理器为transactionManager- -->

<tx:advice id="transactionAdvice" transaction-manager="transactionManager">

<tx:attributes>

<tx:method ame="add*"/>

<tx:method ame="save*"/>

<tx:method ame="update*"/>

<tx:method ame="modify*"/>

<tx:method ame="edit*"/>

<tx:method ame="delete*"/>

<tx:method ame="remove*"/>

<tx:method ame="repair"/>

<tx:method ame="deleteAndRepair"/>

<tx:method name="get*" propagation="SUPPORTS"/>

<tx:method ame="find*" propagation="SUPPORTS"/>

<tx:method ame="load*" propagation="SUPPORTS"/>

<tx:method ame="search*" propagation="SUPPORTS"/>

<tx:method ame="datagrid*" propagation="SUPPORTS"/>

<tx:method name="*" propagation="SUPPORTS"/>

</tx:attributes>

</tx:advice>

<aop:config>

<aop:pointcut id="transactionPointcut" expression="execution(* com.rambo.sdh.service..*Impl.*(..))"/>

<aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice"/>

</aop:config>

上面配置文件的大体意思是说,在包com.rambo.sdh.service..*Impl.*下所执行的已add/save/update.....开头的方法。

方法在执行前后都会被HibernateTransactionManager拦截住,进行事务的开启和关闭。

当然还有一些其他的事情,有兴趣的同学可以debug源码去一探究竟。

昆明Java培训机构的老师说的也差不多了,该方案为javaweb后端解决方案,前端用你想用的渲染技术即可。

上一篇:JAVA鼠标事件监听ACTIONLISTENER
下一篇:kafka知识点:为什么需要消息系统

昆明java培训机构:java未来的发展走向

昆明java培训机构:java学完可以干什么!

昆明java培训机构:如何搞定BAT和华为offer?有这份攻略就够了!

昆明java培训机构:学Java别担心枯燥和无聊

选择城市和中心
贵州省

广西省

海南省

扫一扫

了解更多干货