一、数据持久化和ORM的概念
--转载
1.数据持久化的概念
数据持久化就是将内在中的数据模型转换为存储模型,以及将存储模型转换为内在中的数据模型的统称,数据模型可以是任何数据结构或对象模型,例如JavaBean对象;存储模型可以是关系型数据库表,XML文件,二进制文件等
2.什么是ORM
ORM(Object/Relational Mapping)中文翻译为对象/关系型数据映射,它也可以理解为一种数据持久化技术,其主要是把对象模型,例如JavaBean对象和关系型数据库的表建立对应关系,并且提供了一个通过JavaBean对象去操作数据库表的机制.
3.使用ORM技术的好处
在实际开发中,程序员使用面向对象的技术操作数据,而当要把数据存储起来时,使用的却是关系型数据库,这样就造成了很多的不便,ORM在对象模型和关系数据库的表之间建立了一座桥梁,有了它,程序员就不需要再使用SQL语句操作数据库中的表,直接操作JavaBean对象就可以实现数据的存储,查询,更改和删除等操作,Hibernate就是这样一种技术.
二、现在主流Java Web企业级开发都用哪些框架
--转载
前端ui框架有Bootstrap,jQuery UI,H+还有一些其他的;js框架目前流行的是react,nodejs,angularJS。
后端就是基础的spring hibernate mybatis servlet struts不同组合,针对不同业务选不同的框架
三、Java企业级框架
企业级系统
- 大规模:用户数量多、数据规模大、功能众多
- 性能和安全要求高
- 业务复杂
- 灵活应变
Java技术如何应对
EJB是sun的JavaEE服务器端组件模型,设计目标与核心应用是部署分布式应用程序。简单来说就是把已经编写好的程序(即:类)打包放在服务器上执行。凭借java跨平台的优势,用EJB技术部署的分布式系统可以不限于特定的平台。EJB (Enterprise JavaBean)是J2EE(javaEE)的一部分,定义了一个用于开发基于组件的企业多重应用程序的标准。其特点包括网络服务中心支持和核心开发工具(SDK)。 在J2EE里,Enterprise Java Beans(EJB)称为Java 企业Bean,是Java的核心代码,分别是会话Bean(Session Bean),实体Bean(Entity Bean)和消息驱动Bean(MessageDriven Bean)。在EJB3.0推出以后,实体Bean被单独分了出来,形成了新的规范JPA。--百度百科
EJB的不足
1 学习比较难,开发难度大
2 依赖应用服务器
3 运用大量的设计模式
引入spring之后,spring的依赖注入可以统一管理和生成javabean,哪有需要调用就往哪注入,这种方式大大降低了开发难度, 降低了代码的耦合度,给后期的维护也带来了方便 同时spring的aop还能讲系统中那些类似于日志管理,事务等分布性比较强,但又必须有的代码集中生成,无需开发人员关注,提高工作效率
四、Spring
1.Spring体系结构
Spring框架的核心组件只有三个:Core、Context和Beans。他们构建起了整个Spring的骨骼架构,没有他们就不可能有AOP、Web等上层的特性功能。
AOP包(主要提供面向切面编程的实现),Web(主要提供了Web应用开发的支持及针对Web应用的MVC思想实现) 、ORM(为Hibernate,以及Mybatis这类持久化框架提供支持)、还有Spring MVC(这个是它自带的一个web视图层,可以替代到Sturts2)
2.Spring设计理念
其实Spring就是面向Bean的变成(BOP,Bean Oriented Programming),Bean才是Spring中的真正主角。 Spring就是面向Bean的编程,在Spring中所有对象都可以看成一个Bean。
Bean在Spring 中作用就像Object对OOP的意义一样,没有对象的概念就没有面向对象编程,Spring中没有Bean也就没有Spring存在意义。就像一次演出舞台都准备好了但是却没有演员一样。为什么要Bean这种角色?或者说Bean在Spring中如此重要,这都是由Spring框架的设计目标决定的,Spring为何如此流行,我们使用Spring的原因是什么?思考下,你会发现原来Spring解决了一个非常关键的问题,他可以让你把对象之间的关系转而使用配置文件来管理,也就是他的依赖注入机制,而这个注入关系在一个叫Ioc的容器中管理。Spring正是通过把对象包装在Bean中从而达到对这些对象管理以及一系列额外操作的目的。
那这些核心组件如何协同工作?
前面说Bean是Spring中的关键因素,那Context和Core又有何作用?前面把Bean比作一场演出中的演员的话,那么Context就是这场演出的舞台背景,而Core就是应该是演出的道具了。只有他们在一起才能具备演出一场好戏的最基本条件。当然有最基本的条件还不能使这场演出脱颖而出,还要他表演的节目足够的经餐,这些节目就是Spring提供的特色功能了。
那它是怎么管理这些Bean的呢?
Spring把所有的Bean及它们之间的依赖关系以配置文件的方式组装起来,在一个叫IoC(Inversion of Control)的容器中进行管理,这也就是Spring的核心设计思想之一依赖注入机制,Spring的另一个核心设计思想叫做AOP。
通过集成实现的接口就知道他具有spring里面经典的工厂方法,还有对国际化支持的Message,以及配置信息的Resource,还有spring支持的发布和监听事件功能。一个Context基本上把spring具有的核心功能都包裹起来了,那么这就是spring框架运行需要的环境,也就是常说的上下文。任何一个框架运行都通过一个类来进行描述它执行时的环境,ServletContext也是一样,就是Servlet环境信息。可以将context理解为一个框架执行信息的载体,可以理解问一个框架的门面(门面模式),将框架内部的各个组件信息都通过一个context暴露给外部。
上下文模块建立在由核心和bean模块提供的坚实基础上,他是访问定 义和配置的任何对象的媒介。ApplicationContext接口是上下文模块 的重点。
3.Spring的优点
- 低侵入式设计
- 独立于各种应用服务器
- 依赖注入特性将组件关系透明化,降低了耦合度
- 面向切面编程特性允许将通用任务进行集中式处理
- 与第三方框架的良好整合
Spring作为一个开源的轻量级的IOC和AOP容器框架,具有以下优点:
1、低侵入式设计:非入侵式设计,基于Spring开发的应用一般不依赖于Spring的类
2、独立于各种应用服务器,真正实现:一次编写,到处运行。
3、Spring的依赖注入特性使Bean与Bean之间的依赖关系变的完全透明,降低了耦合度:使用SpringIOC容器,将对象之间的依赖关系交给Spring,降低组件之间的耦合性,让我们更专注于应用逻辑
4、它的面向切面编程特性允许将一些通用任务如安全、事务、日志等进行集中式处理
5、并且它还提供了与第三方持久层框架的良好整合,并简化了底层数据库访问
6、高度的开放性(可以和Struts2、Hibernate、MyBatis、CXF等很多主流第三方框架无缝整合)
五、控制反转 / 依赖注入
1.概念
将组件对象的控制权从代码本身转移到外部容器
- 组件化的思想:分离关注点,使用接口,不再关注实现
- 依赖的注入:将组件的构建和使用分开
目的:解耦合。实现每个组件时只关注组件内部的事情
当某个角色(比如一个java示例,调用者)需要另一个角色(另一个java示例,被调用者)的协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的示例。但是在spring里,创建被调用者的工作不再由调用者来完成。因此被称为控制反转;创建被调用者实例的工作通常由spring容器来完成,然后注入调用者,因此也称为依赖注入。这样给程序带来很大的灵活性,这样也实现了我们的接口和实现的分离。
简而言之也就是说我们要获得一个对象,不由我们开发者自己创建,而是由我们的容器来注入给我们的程序来使用.
2.分类
- 设值注入
- 构造注入
- p命名空间注入
六、面向切面编程(AOP)
1.原来的业务层代码
public class UserServiceImpl implements UserService {
private static final Logger log = Logger.getLogger(UserServiceImpl.class);
public boolean addNewUser(User user) {
log.info(“添加用户 ” + user.getUsername());//记录日志
SqlSession sqlSession = null;
boolean flag = false;
//异常处理
try {
sqlSession = MyBatisUtil.createSqlSession();
if (sqlSession.getMapper(UserMapper.class).add(user) > 0)
flag = true;
sqlSession.commit(); //事务控制
} catch (Exception e) {
log.error("添加用户 " + user.getUsername() + "失败", e); //记录日志
sqlSession.rollback(); //事务控制
flag = false;
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
return flag;
}
}
2.AOP概念
- 所谓面向切面编程,是一种通过预编译和运行期动态代理的方式实现在不修改源代码的情况下给程序动态添加功能的技术
- AOP实际上是由目标类的代理类实现的
- AOP代理其实是由AOP框架动态生成的一个对象,该对象可作为目标对象使用。AOP代理包含了目标对象的全部方法,但是AOP代理中的方法与目标对象的方法存在差异,AOP方法在特定切入点添加了增强处理,并回调了目标对象的方法。
AOP的目标:让我们可以“专心做事”
AOP原理:
- 将复杂的需求分解出不同方面,将散布在系统中的公共功能集中解决
- 采用代理机制组装起来运行,在不改变原程序的基础上对代码段进行增强处理,增加新的功能
AOP理解:
业务处理的主要流程就是核心关注点,与之关系不大的部分就是横切关注点。横切关注点的一个特点就是:他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事务处理。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。
3.AOP相关术语
增强处理(Advice)
- 前置增强
- 后置增强
- 环绕增强、异常抛出增强、最终增强等类型
切入点(Pointcut)
连接点(Join Point)
切面(Aspect)
目标对象(Target object)
AOP代理(AOP proxy)
织入(Weaving)
增强(Adivce):
又翻译成通知,定义了切面是什么以及何时使用,描述了切面要完成的工作和何时需要执行这个工作。是织入到目标类连接点上的一段程序代码。增强包含了用于添加到目标连接点上的一段执行逻辑,又包含了用于定位连接点的方位信息。(所以spring提供的增强接口都是带方位名:BeforeAdvice、(表示方法调用前的位置)AfterReturninAdvice、(表示访问返回后的位置)ThrowAdvice等等,所以只有结合切点和增强两者一起才能确定特定的连接点并实施增强逻辑)
切入点(Pointcut):
Advice定义了切面要发生“故事”和时间,那么切入点就定义了“故事”发生的地点。例如某个类或者方法名,Spring中允许我们使用正则来指定。 连接点(Joinpoint):切入点匹配的执行点称作连接点。如果说切入点是查询条件,那连接点就是被选中的具体的查询结果。程序执行的某个特定位置,程序能够应用增强代码的一个“时机”,比如方法调用或者特定异常抛出
切面(Aspect):
切点和增强组成切面。它包括了横切逻辑的定义,也包括了连接点的定义。Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中
代理(Proxy):AOP框架创建的对象。一个类被AOP织入增强之后,就产生了一个结果类,它是融合了原类和增强逻辑的代理类。
目标对象(Target):增强逻辑的织入的目标类
织入(Weaving):将增强添加到目标类具体连接点上的过程。AOP有三种织入的方式:编译期织入、类装载期织入、动态代理织入(spring采用动态代理织入)
4.使用Spring AOP实现日志输出
实现步骤
- 在项目中添加Spring AOP的jar文件
- (spring-aop-3.2.13.RELEASE.jar || aopalliance-1.0.jar || aspectjweaver-1.6.9.jar || cglib-nodep-2.1.3.jar(已内联在Spring core中))
- 编写前置增强和后置增强实现日志功能
- 编写Spring配置文件,对业务方法进行增强处理
- 编写代码获取带有增强处理的业务对象
5.怎样使用AOP
1)目标方法
public class UserServiceImpl implements UserService {
//…省略代码
public void addNewUser(User user) {
dao.save(user);
}
}
2)增强处理
public class UserServiceLogger {
private static Logger log=Logger.getLogger(UserServiceLogger.class);
/*前置增强*/
public void before(JoinPoint jp) {//JoinPoint连接点对象
log.info("调用" + jp.getTarget() + "的" + jp.getSignature().getName() + " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
}
/*后置增强*/
public void afterReturning(JoinPoint jp, Object result) {
log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName() + " 方法。方法返回值:" + result);
}
// jp.getTarget():连接点方法所在的目标类,jp.getArgs()连接点方法参数数组,jp.getSignature()
}
3)定义切入点
- 切入点:简单的说,就是连接点的查询条件
<aop:config>
<!--切入点表达式,符合该表达式的方法可以被织入增强处理-->
<aop:pointcut id="pointcut" expression="execution(public void addNewUser(entity.User))"/>
</aop:config>
- 表达式匹配规则举例
public * addNewUser(entity.User): “*”表示匹配所有类型的返回值。
public void *(entity.User): “*”表示匹配所有方法名。
public void addNewUser(..): “..”表示匹配所有参数个数和类型。
* com.service.*.*(..):匹配com.service包下所有类的所有方法。
* com.service..*.*(..):匹配com.service包及其子包下所有类的所有方法
4)织入增强处理
- 织入:在切入点插入增强处理
<aop:config>
<aop:pointcut id="pointcut" expression="execution(public void addNewUser(entity.User))"/>
<!--增强处理对象-->
<aop:aspect ref="userServiceLogger">
<!-- 前置增强处理 method:被织入的方法 pointcut-ref:切入点-->
<aop:before method="before" pointcut-ref="pointcut"></aop:before>
<!-- 后置增强处理 指定需要注入返回值的属性名为result-->
<aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
</aop:aspect>
</aop:config>
6.异常抛出增强
7.最终增强
8.环绕增强
8.常用增强处理类型
增强处理类型 | 特 点 |
Before | 前置增强处理,在目标方法前织入增强处理 |
AfterReturning | 后置增强处理,在目标方法正常执行(不出现异常)后织入增强处理 |
AfterThrowing | 异常增强处理,在目标方法抛出异常后织入增强处理 |
After | 最终增强处理,不论方法是否抛出异常,都会在目标方法最后织入增强处理 |
Around | 环绕增强处理,在目标方法的前后都可以织入增强处理 |
9.Spring AOP配置元素
AOP配置元素 | 描 述 |
<aop:config> | AOP配置的顶层元素,大多数的<aop:*>元素必须包含在<aop:config>元素内 |
<aop:pointcut> | 定义切点 |
<aop:aspect> | 定义切面 |
<aop:after> | 定义最终增强(不管被通知的方法是否执行成功) |
<aop:after-returning> | 定义after-returning增强 |
<aop:after-throwing> | 定义after-throwing增强 |
<aop:around> | 定义环绕增强 |
<aop:before> | 定义前置增强 |
<aop:aspectj-autoproxy> | 启动@AspectJ注解驱动的切面 |
<!-- 配置切面-->
<aop:config>
<!-- 定义切入点(某方法) 参数类型要传其全路径-->
<!-- <aop:pointcut id="addPo" expression="execution(public String add(java.lang.String))"/>-->
<aop:pointcut id="addPo" expression="execution(* cn.gwj.service..*.*(..))"/>
<!--引用包含增强方法的bean-->
<aop:aspect ref="aopLogger">
<!-- 定义前置增强 pointcut-ref已经定义的切点方法-->
<aop:before method="before" pointcut-ref="addPo"/>
<!--定义后置增强 pointcut-ref已经定义的切点方法 returning在增强方法里面定义的返回值参数-->
<aop:after-returning method="after" pointcut-ref="addPo" returning="result"/>
<!-- 定义最终增强-->
<aop:after method="aft" pointcut-ref="addPo"/>
<!-- 异常-->
<aop:after-throwing method="exc" pointcut-ref="addPo" throwing="e"/>
<!-- 环绕增强-->
<aop:around method="around" pointcut-ref="addPo"/>
</aop:aspect>
</aop:config>
七、使用注解实现IoC
-
使用Java标准注解完成装配
-
使用注解定义切面
AspectJ
- 面向切面的框架,它扩展了Java语言,定义了AOP 语法,能够在编译期提供代码的织入
@AspectJ
- AspectJ 5新增的功能,使用JDK 5.0 注解技术和正规的AspectJ切点表达式语言描述切面
Spring通过集成AspectJ实现了以注解的方式定义增强类,大大减少了配置文件中的工作量
- 利用轻量级的字节码处理框架asm处理@AspectJ中所描述的方法参数名
注:使用@AspectJ,首先要保证所用的JDK 是5.0或以上版本
<!--使用扫描注解注入的包-->
<context:component-scan base-package="cn.gwj"/>
<!-- 开启使用注解驱动切面-->
<aop:aspectj-autoproxy/>