-
AOP,面向切面编程,与垂直业务功能,实现程序功能的统一维护。
主要功能:日志记录,性能统计,安全控制,事物处理,异常处理等等。(事务处理:任何操作数据库的方法,尤其是增删改,需要事物的处理,使用AOP时,执行到某种类型的方法,或者某一层的类,自动开启事务和获取连接、提交事务、关闭事务的步骤,简化了操作)
AOP实现方式:1、预编译方式。(AspectJ) 2、运行期动态代理。(JDK动态代理、CGLib动态代理)(SpringAOP、JbossAOP)
切面的理解:例如系统中有产品管理、订单管理、服务管理等等模块(子功能),任一模块(子功能),都需要记录它的日志,控制它的事务,以及做一些安全验证的功能。但是如果在每一个模块(子功能)中去设计日志、事务、安全验证,会带来大量工作量,尤其当项目达到一定规模时,比如修改日志记录的方式,那么则需要修改每一个模块的日志功能,通过切面方式对开发人员是不可见的,当执行任一模块时,通过预编译或者运行期动态代理方式,都会去记录它的日志,实现了一处写功能,处处可实现的方式,对于开发人员允许不知道有这样功能的存在,这样就简化了操作(修改日志、编写事物等),业务功能横向走,切面垂直业务功能。
二、AOP基本概念(切面—>织入—>目标对象—>切入点—>连接点—>通知—>引入—>AOP代理:“切面”要执行的动作,通过“织入”与所有功能模块进行联系,又通过“目标对象”找到具体功能模块,通过“切入点”将要查找某个功能的某个方法,通过“连接点”找到该功能的特定方法的开始,通过“通知”将要执行何种切面的动作,通过“引入”引入该动作用到的对象和方法,通过“AOP代理”实现该方法。)
AOP相关概念:
1、切面(Aspect):一个关注点(事务),这个关注点可能会横切多个对象(产品管理、订单管理)。
2、连接点(Joinpoint):程序执行过程中的某个特定的点。(一个类中执行的某个方法的开始)。
3、通知(Advice):在切面的某个特定的连接点上执行的动作(方法执行的时候,切面额外执行的动作,比如说方法执行时,开启事物提交功能)。
4、切入点(Pointcut):匹配连接点的断言,在AOP中通知和一个切入点表达式关联(在切面中匹配一个具体的连接点(某个功能的方法的开始))。
5、引入(Introduction):在不修改类代码的前提下,修改的是字节码文件,为类添加新的方法和属性。(类似于编译期动态的修改class文件去增加新的属性和方法,源代码中并没有这样的属性和方法),取决于使用AspectJ和SpringAOP的实现方式,使用方式不同,为类添加属性和方法的方式是有区别的。
6、目标对象(Target Object):被一个或者多个切面所通知的对象。(例如存在一个订单的service(对象)和一个商品的service(对象),执行该模块的功能时,切面会通知相对应的service,在执行数据库操作时,去加上事物的控制,这两个service就是目标对象)。
7、AOP代理(AOP Proxy):AOP框架创建的对象,用来实现切面契约(aspect contract),包括通知方法执行等功能(这里执行的方法指的是切面里的执行相应操作所用到的方法)开发时不知道这个对象存在的,也不清楚会创建成什么样子。
8、织入(Weaving):把切面连接到其他的应用程序类型或者对象上,并创建一个被通知的对象,分为:编译时织入、类加载时织入、执行时织入。(使切面和对象(模块功能)牵连起来)
Advice(通知)的类型(在切面某个特定连接点执行的动作)
前置通知(Before advice):在某连接点(join point)(某个功能方法开始执行前)之前执行的通知,但不能阻止连接点前的执行(除该方法外的其他方法的执行)(除非它抛出一个异常)。
返回后通知(After returning advice):在某连接点(方法)正常完成后执行的通知(将要执行的切面功能)。
抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知(将要执行切面的功能)。
后通知(After(finally)advice):当某连接点(方法)退出的时候执行的通知(切面将要执行的功能)(不论是正常返回还是异常退出都会执行的通知)。
环绕通知(Around Advice):包围一个连接点(join point)的通知(在整个方法的内部都有切面要执行的功能存在,不分前后)。
Spring框架中AOP的用途:
用途1:提供了声明式的企业服务(也可以是其他服务,例如互联网服务),特别是EJB(重量级框架)的替代服务的声明。
用途2:允许用户定制自己的方面(切面),以完成OOP(面向对象编程,模拟世界中行为和方式,可以理解为实现一个功能的顺序)与AOP(横切的方式,可以理解为各个功能之间横切的一种功能)的互补使用,可以实现自己横切的功能。
三、Spring中的AOP(Spring中AOP的实现方式以及特点)
特点1:纯java实现,无需特殊的编译过程(普通代码需要加载才能执行),不需要控制类加载器层次。可以更好的进行控制(使用类加载器应当谨慎,容易方法生ClassNotFound异常这种情况)。
特点2:目前只支持方法执行连接点(通知Spring Bean的方法执行),(在执行某方法时,才去执行切面的功能)。
特点3:SpringAOP不是为了提供最完整的AOP实现(尽管它非常强大);而是侧重于提供一种AOP实现和Spring IoC容器之间的整合,用于帮助解决企业应用中的常见问题。
特点4:SpringAOP不会与AspectJ(完整的、全面的AOP解决方案)竞争,也不会提供综合全面的AOP解决方案。
有接口和无接口的SpringAOP实现区别:(一个类是否实现了某个接口,例如一个ProductService接口,一个ProductServiceImpl实现了该接口,在这类上切入的切面就是有接口的AOP)
SpringAOP对于有接口的使用标准的JavaSE动态代理作为AOP代理,这使得任何接口(或者接口集)都可以被代理。
SpringAOP对于没有接口的实现类中使用CGLIB代理(如果一个业务对象并没有实现一个接口)
四、Schema-based 实现AOP(基于配置文件实现AOP)
五、API实现AOP(基于API实现AOP)
六、AspectJ实现AOP
查看全部 -
@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。
1、共同点
两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。
2、不同点
(1)@Autowired
@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
public class TestServiceImpl { // 下面两种@Autowired只要使用一种即可 @Autowired private UserDao userDao; // 用于字段上 @Autowired public void setUserDao(UserDao userDao) { // 用于属性的方法上 this.userDao = userDao; } }
@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。如下:
public class TestServiceImpl { @Autowired @Qualifier("userDao") private UserDao userDao; }
(2)@Resource
@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
public class TestServiceImpl { // 下面两种@Resource只要使用一种即可 @Resource(name="userDao") private UserDao userDao; // 用于字段上 @Resource(name="userDao") public void setUserDao(UserDao userDao) { // 用于属性的setter方法上 this.userDao = userDao; } }
注:最好是将@Resource放在setter方法上,因为这样更符合面向对象的思想,通过set、get去操作属性,而不是直接去操作属性。
@Resource装配顺序:
①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。
@Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。
---一只noob
查看全部 -
@Bean:由SpringIoc容器配置和初始化对象,类似于XML配置文件的<bean/>,。(一般@Bean 需要在配置类中使用,即类上需要加上@Configuration注解)
查看全部 -
@Resource 适用于成员变量 一个参数的set方法,@Qualifier 使用于构造方法和多参数方法。
@qualifier:一般和@Autowired一起使用,有时候类型是接口的成员变量可能有多个实现类,按类型自动注入时可能会有多个Bean实例的情况,可以使用@Qualifier注解缩小范围(或指定唯一),指定使用哪个接口的实现类来赋给当前的成员变量,也可用于指定单独的构造器或方法参数。
查看全部 -
autowired注解数组和map
查看全部 -
autowired的参数required的说明。required默认值是false。
查看全部 -
Autowired注解可用于set方法、成员变量和构造函数。是常用的注解方法。autowired通过Type对bean进行注入的,而不是name。
查看全部 -
java的注解在jdk5之后引入。
Bean管理的注解实现及例子
1、Classpath扫描与组件管理
定义:从Spring3.0开始,Spring JavaConfig项目提供很多特性,包括通过注解定义Bean,而不是使用XML。
@Component:通用型注解,可用于任何Bean,可以注解任何类。
@Repository,@Service,@Controller是更有针对性的注解。(component的子注解)
@Repository:通常用于注解DAO层,即持久层。
@Service:通常用于注解Service层,即服务层。
@Controller:通常用于Controller层,即控制层(MVC).
查看全部 -
ResourceLoader 注入方式
查看全部 -
resourceloader例子
查看全部 -
resources
查看全部 -
自动装配:无需在xml中指定property或是constructor-arg属性。
byName:根据set中参数的bean id装配bean实例。
byType:根据set中参数的bean类型装配bean实例。
constructor:IOC容器查找有无构造器方法中的参数的类型
查看全部 -
定义:Spring中提供了一些以Aware结尾的接口,实现了Aware接口的Bean在被初始化后,可以获取相应资源,通过Aware接口,可以对Spring相应资源进行操作(慎重),前提配置<bean>标签,并使用ioc容器去记性加载。
ApplicationContextAware:Bean类实现该接口,通过覆盖该接口提供的setApplicationContext方法,可以直接获取spring上下文,而不用我们自己手动创建。
BeanNameAware:Bean类实现该接口,通过覆盖该接口提供的setBeanName方法,可以得到bean的name(id)
同时实现两个接口,通过setBeanName可以得到bean的name,通过applicationContext.getBean(this.name)得到此bean的实例。
查看全部 -
bean的生命周期包括以下四部分:定义、初始化、使用、销毁。
bean的初始化(context启动时加载Bean配置文件并生成Bean实例)包括两种方式:实现org.springframework.beans.factory.InitializingBean接口,覆盖afterPropertitesSet方法或者配置init-method。
bean使用:取出bean实例,调用其方法。
同样bean的销毁(销毁bean容器创建的所有bean实例)也有两种方式,实现org.springframework.beans.factory.DisposableBean覆盖destory方法或配置destory-method。
或者配置全局的初始化、销毁方法。
查看全部 -
Spring 注入是指在启动Spring容器加载bean配置的时候完成对变量的赋值行为。注入方式分为:设值注入和构造注入。设值注入和构造注入则通过配置上的差异来区分。设值注入需要在调用类加set方法,构造注入是在调用类的构造方法传参
查看全部
举报