使用注解配置spring

步骤:

1. 导包4(core/bean/context/spel)+1(logging)+spring-aop包(新版spring需要导入这个包)

2. 为主配置文件引入新的命名空间(约束)  Context约束

3. 开启使用注解代理配置文件

<context:component-scan base-package="com.domain">  指定扫描 com.domain包下面所有类的注解(同时会扫描子包里面的类)

4. 在类中使用注解完成配置

@Component("user")public class User {
private String name;
private Integer age; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", car=" + car + "]";
}
}

将对象注册到容器

@Component(“user”)

@Service(“user”)  service层

@Controller(“user”)  web层

@Repository(“user”)  dao层

本质上这四个功能都是一样  只是为了见名知意

修改对象的作用范围

@Scope(scopeName=”prototype”) 指定对象的作用范围         同样也是作用在实体上面

值类型注入

@Value("tom")
private String name;

通过反射来为Field赋值 ,但是这样破坏了封装性

通过set方法来赋值  推荐使用

@Value("24")
public void setAge(Integer age) {
this.age = age;
}

引用类型注入

1.使用AutoWired 自动装配

@Component("user")
public class User {
@Autowired
private Car car; setCar/getCar ...
} @Component
class Car{
private String cName;
private String color;
get/set ...
} 注意:使用自动装配,被装配的字段 也要在容器有 可以没有名字

这种方式有一个坏处:如果匹配多个类型一致的对象,将无法选择具体注入哪一个对象

解决办法:使用 Qualifier("car")  通过该注解来告诉 spring容器自动装配哪个名称的对象

注意:Qualifier和AutoWired要一起使用

@Resource(name="car") 手动注入,指定注入哪个名称的对象

@Resource(name="car")
private Car car;

初始化 | 销毁方法

@PostConstruct                      // 在对象被创建以后调用   相当于配置文件中定义的init-method
public void init() {
System.out.println("init method");
} @PreDestroy // 在对象被销毁前调用 destory-method
public void destory(){
System.out.println("destory method");
}

spring与junit整合测试

1.导包    4+2+aop+test

2.配置注解

@RunWith(SpringJUnit4ClassRunner.class)      // 帮我们创建容器
@ContextConfiguration("classpath:applicationContext.xml") //指定创建容器时使用的配置文件
public class Student { @Value("wanglei")
private String name; @Test
public void test() {
System.out.println(name);
} @Value("24")
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}

spring中的aop

aop思想介绍  横向重复代码 ,纵向抽取

例如:解决乱码问题   管理事务  action拦截器

spring中的aop概念 ------> spring能够为容器中管理的对象生成动态代理对象

以前我们要使用动态代理,需要自己调用下面的方法

Proxy.newProxyInstance(xx,xx,xx) 生成代理对象

现在spring能够帮助我们生成代理对象

spring实现aop的原理

1.动态代理(优先) :   被代理对象必须要实现接口,才能产生代理对象,如果没有接口将不能使用动态代理技术。

2.cglib代理(没有接口) : 第三方代理技术,cglib代理可以对任何类生成代理,代理的原理是对目标对象进行继承代理.

但是如果目标对象被final修饰,那么该类无法被cglib代理.

步骤:

1.创建service的接口是实现类

public interface UserService {
void save();
void add();
void delete();
void find();
} public class UserServiceIml implements UserService {
public void save() {
System.out.println("save");
}
public void add() {
System.out.println("add");
}
public void delete() {
System.out.println("delete");
}
public void find() {
System.out.println("find");
}
}

2.使用cglib代理生成代理对象

public class Test implements MethodInterceptor{

    public UserService getService() {
Enhancer en=new Enhancer(); //用于生成代理对象
en.setSuperclass(UserServiceIml.class);//对谁设置代理
en.setCallback(this); //代理要做什么
UserService service = (UserService) en.create();//创建代理对象
return service;
} @Override proxyObj 目标类的实例 method 目标类方法的反射实例 arg 参数 methodProxy 代理类实例
public Object intercept(Object proxyObj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
System.out.println("打开事务!");
Object returnValue = methodProxy.invokeSuper(proxyObj, arg);
System.out.println("提交事务!");
return returnValue;
}
}

3.测试

public static void main(String[] args) {
Test test = new Test();
UserService service = test.getService();
service.save();
}

AOP名词学习

Joinpoint(连接点):目标对象中,所有可以增强的方法

Pointcut(切入点): 目标对象,已经增强的方法

Advice(通知/增强):增强的代码

Target(目标对象): 被代理的对象

Weaving(织入):将通知应用到切入点的过程

Proxy(代理):将通知织入到目标对象之后,形成代理对象

Aspect(切面):切入点 + 通知

spring中的aop演示

步骤:

1.导包4(core + bean + spel + context)+2  + 2(aop + aspect) + 2(allowiance + weaving)

aop包 + aspect包 + aopalliance + weaver

2.准备目标对象

用到spring2.5版本的jar文件,如果用jdk1.7可能会有问题

需要升级aspectj组件,即使用aspectj-1.8.2版本中提供jar文件提供

3.准备通知

前置通知   目标方法运行之前调用

后置通知(如果出现异常不会调用)  在目标方法运行之后调用

环绕通知   在目标方法之前和之后都调用

异常拦截通知:如果出现异常,就会调用

后置通知(无论是否出现异常都会调用) :在目标方法运行之后调用

public class MyAdvice {
//前置通知
public void before() {
System.out.println("前置通知");
}
//后置通知
public void afterReturn() {
System.out.println("后置通知(如果出现异常不会被调用)");
}
//环绕通知
public Object around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("这是环绕通知之前的部分");
Object proceed = pjp.proceed();//调用目标方法
System.out.println("这是环绕通知之后的部分");
return proceed;
}
//异常拦截通知
public void afterException() {
System.out.println("出现异常了");
}
//后置通知
public void after() {
System.out.println("后置通知(出现异常也会调用)");
}
}

4.配置进行织入,将通知织入目标对象中

准备工作:导入AOP(约束)命名空间

1.配置目标对象  将具体的实现类(而不是接口添加进来)   因为是为 实现类来创建代理对象

<bean name="userService" class="..."></bean>

2.配置通知对象

<bean name="myAdvice" class="...">

3.配置切入点

<aop:pointcut expression="execution(* cn.itcast.service.*ServiceImpl.*(..))" id="pc"/>

execution有以下几种形式

public void cn.itcast.service.UserServiceImpl.save()  具体的某个方法
void cn.itcast.service.UserServiceImpl.save()   
* cn.itcast.service.UserServiceImpl.save()      任意返回值
* cn.itcast.service.UserServiceImpl.*()           任意方法名/任意返回值
* cn.itcast.service.*ServiceImpl.*(..)              任意参数/ 任意返回值/ 任意方法名
* cn.itcast.service..*ServiceImpl.*(..)       还会找这个下面的子包

<aop:config>
<aop:pointcut expression="execution(* com.domin.*Service.*(..))" id="pc"/> //表示拦截哪些方法
<aop:aspect ref="advice">
<aop:before method="before" pointcut-ref="pc"/>
<aop:around method="around" pointcut-ref="pc"/>
<aop:after-throwing method="afterException" pointcut-ref="pc"/>
<aop:after method="after" pointcut-ref="pc"/>
<aop:after-returning method="afterReturn" pointcut-ref="pc"/>
</aop:aspect>
</aop:config>
<!-- 【拦截所有public方法】 -->
<!--<aop:pointcut expression="execution(public * *(..))" id="pt"/>--> <!-- 【拦截所有save开头的方法 】 -->
<!--<aop:pointcut expression="execution(* save*(..))" id="pt"/>--> <!-- 【拦截指定类的指定方法, 拦截时候一定要定位到方法】 -->
<!--<aop:pointcut expression="execution(public * cn.itcast.g_pointcut.OrderDao.save(..))" id="pt"/>--> <!-- 【拦截指定类的所有方法】 -->
<!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.*(..))" id="pt"/>--> <!-- 【拦截指定包,以及其自包下所有类的所有方法】 -->
<!--<aop:pointcut expression="execution(* cn..*.*(..))" id="pt"/>--> <!-- 【多个表达式】 -->
<!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) || execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
<!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) or execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
<!-- 下面2个且关系的,没有意义 -->
<!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) &amp;&amp; execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
<!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) and execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>--> <!-- 【取非值】 -->
<!--<aop:pointcut expression="!execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
<aop:pointcut expression=" not execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/> <!-- 切面 -->
<aop:aspect ref="aop">
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pt"/>
</aop:aspect>

调用顺序

1.没有发生异常的情况下

前置通知
     这是环绕通知之前的部分
     save method
     这是环绕通知之后的部分
    后置通知(出现异常也会调用)
    后置通知(如果出现异常不会被调用)

2.发生异常的情况下

前置通知
    这是环绕通知之前的部分
    出现异常了
    后置通知(出现异常也会调用)

注解配置实现动态代理

1.导包

2.配置

同样需要加入  <bean name="userService" class="..."></bean>  和 <bean name="myAdvice" class="...">

3.使用注解来实现代理

4.在配置文件中加入 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>  表示开启使用注解完成织入

5.测试

@Aspect                                                          指定一个类为切面类

@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")  指定切入点表达式

@Before("pointCut_()")                                前置通知: 目标方法之前执行

@After("pointCut_()")                                   后置通知:目标方法之后执行(始终执行)

@AfterReturning("pointCut_()")             返回后通知: 执行方法结束前执行(异常不执行)

@AfterThrowing("pointCut_()")                  异常通知:  出现异常时候执行

@Around("pointCut_()")                               环绕通知: 环绕目标方法执行

@Component
@Aspect // 指定当前类为切面类
public class Aop { // 指定切入点表单式: 拦截哪些方法; 即为哪些类生成代理对象 @Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")
public void pointCut_(){
} // 前置通知 : 在执行目标方法之前执行
@Before("pointCut_()")
public void begin(){
System.out.println("开始事务/异常");
} // 后置/最终通知:在执行目标方法之后执行 【无论是否出现异常最终都会执行】
@After("pointCut_()")
public void after(){
System.out.println("提交事务/关闭");
} // 返回后通知: 在调用目标方法结束后执行 【出现异常不执行】
@AfterReturning("pointCut_()")
public void afterReturning() {
System.out.println("afterReturning()");
} // 异常通知: 当目标方法执行异常时候执行此关注点代码
@AfterThrowing("pointCut_()")
public void afterThrowing(){
System.out.println("afterThrowing()");
}
// 环绕通知:环绕目标方式执行
@Around("pointCut_()")
public void around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕前....");
pjp.proceed(); // 执行目标方法
System.out.println("环绕后....");
}
}
<!-- 开启注解扫描 -->
<context:component-scan base-package="cn.itcast.e_aop_anno"></context:component-scan> <!-- 开启aop注解方式 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

Spring Web  Spring对web模块的支持。

可以与struts整合,让struts的action创建交给spring

spring mvc模式

Spring DAO  Spring 对jdbc操作的支持  【JdbcTemplate模板工具类】

Spring ORM  spring对orm的支持:

既可以与hibernate整合,【session】

也可以使用spring的对hibernate操作的封装

SpringEE   spring 对javaEE其他模块的支持

spring学习2的更多相关文章

  1. spring 学习之 bean 的注入方式 property和constructor-arg的使用方式

    spring 学习之 bean 的注入方式 property和constructor-arg的使用方式. bean的注入方式: property 注入是: 通过setxx方法注入. construct ...

  2. Spring学习之AOP总结帖

    AOP(面向方面编程),也可称为面向切面编程,是一种编程范式,提供从另一个角度来考虑程序结构从而完善面向对象编程(OOP). 在进行 OOP 开发时,都是基于对组件(比如类)进行开发,然后对组件进行组 ...

  3. Spring学习之第一个AOP程序

    IOC和AOP是Spring的两大基石,AOP(面向方面编程),也可称为面向切面编程,是一种编程范式,提供从另一个角度来考虑程序结构从而完善面向对象编程(OOP). 在进行 OOP 开发时,都是基于对 ...

  4. MyEclipse Spring 学习总结三 SpringMVC

    MyEclipse Spring 学习总结三 SpringMVC 一.SpringMVC原理 1.Springmvc 框架介绍 1)Spring 框架停工了构建Web应用程序的全功能MVC模块.Spr ...

  5. Spring学习 Ioc篇(一 )

    一直以来忙于项目的开发,Spring虽然不用,一直想系统地学习一下,想看看它的源码,都没有时间,这段时间比较充裕,就索性先把Spring学习下,熟悉各个功能再去探究它内部的实现.就从Ioc篇开始学习. ...

  6. Spring学习(三)——Spring中的依赖注入的方式

    [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...

  7. Spring学习(二)——Spring中的AOP的初步理解[转]

      [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...

  8. 【Spring学习笔记-MVC-3.1】SpringMVC返回Json数据-方式1-扩展

    <Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...

  9. Spring学习8-Spring事务管理

      http://blog.sina.com.cn/s/blog_7ffb8dd501014e0f.html   Spring学习8-Spring事务管理(注解式声明事务管理) 标签: spring注 ...

  10. Spring学习之Ioc控制反转(1)

    开始之前: 1. 本博文为原创,转载请注明出处 2. 作者非计算机科班出身,如有错误,请多指正 ---------------------------------------------------- ...

随机推荐

  1. java中super()和this()、super和this的区别

    1.super()和this()区别: super():调用父类无形参的构造方法: super(形参):调用父类中某个带形参的构造方法: this(形参):调用本类中另一种形式的构造方法: 注意:放在 ...

  2. vertica创建新用户并授权

    1.创建用户,并设置密码: create user user1 identified by 'pwd1'; 2.把角色授权给用户(dbduser是普通角色): grant dbduser to use ...

  3. Spring69道面试题

    Spring 概述 1. 什么是spring? Spring 是个java企业级应用的开源开发框架.Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用.Spring  ...

  4. centos6.5 安装openresty

    [1]centos6.5 安装openresty步骤 (1)基础依赖库安装 1.1 yum install pcre-devel openssl-devel gcc curl (2)openResty ...

  5. 图解微信小程序---轮播图

    图解微信小程序---轮播图 代码笔记 第一步:在页面创建swiper组件 第二步:编写js页面 注意事项:wx:for渲染我们js中的图片数组,item默认写法,获取我们的图片数组中的图片,可通过增加 ...

  6. 深入V8引擎-写在前面

    这一篇不打算讲技术,聊点别的吧,写这个的原因主要是看到了我博客园的签名,开始这个最终源码系列前想说点什么. 转行前端(达成) 入行1年vue源码(达成).webpack源码(半达成) 入行2年争取读通 ...

  7. Linux 笔记 - 第二十二章 Nginx 配置 SSL

    一.前言 基础知识 1.1 公钥密码体制(public-key cryptography) 公钥密码体制分为三个部分,公钥.私钥.加密解密算法,它的加密解密过程如下: 加密:通过加密算法和公钥对内容( ...

  8. Java Base64Utils ----Utils

    Java Base64Utils   目录   Java Base64Utils 7 /**  * <html>  * <body>  *  <P> Copyrig ...

  9. Visual Studio 2019 正式版今日发布 key

     Visual Studio 2019 EnterpriseBF8Y8-GN2QH-T84XB-QVY3B-RC4DFVisual Studio 2019 ProfessionalNYWVH-HT4X ...

  10. 我遇到的WPF的坑

    转自 林德熙Blog 本文:我遇到的WPF的坑 目录 单例应用在多实例用户无法使用 标记方法被使用 当鼠标滑过一个被禁用的元素时,让ToolTip 显示 获取设备屏幕数量 获取当前域用户 绑定资源文件 ...