课程咨询 :186 8716 1620      qq:2066486918

昆明Java培训 > 达内新闻 > Java程序员:给你一个稳妥的后端解决方案
  • Java程序员:给你一个稳妥的后端解决方案

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

  • 昆明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--零基础全日制班

开班日期:11/30

Java--零基础业余班

Java--零基础业余班

开班日期:11/30

Java--周末提升班

Java--周末提升班

开班日期:11/30

Java--零基础周末班

Java--零基础周末班

开班日期:11/30

  • 网址:http://km .java.tedu.cn      地址:昆明市官渡区春城路62号证券大厦附楼6楼
  • 课程培训电话:186 8716 1620      qq:2066486918    全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56