实现AOP,主要通过两类方式:
1.采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;
2.采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间输入有关“方面”的代码。
方式不同效果却相同,具有的特性也是相同的:
·连接点(join point):是程序执行中的一个精确执行点,例如类中的一个方法。它是一个抽象的概念,在实现AOP时,并不需要去定义一个join point。
·切入点(point cut):本质上是一个捕获连接点的结构。在AOP中,可以定义一个point cut,来捕获相关方法的调用。
·通知(advice):是point cut的执行代码,是执行“方面”的具体逻辑。
·方面(aspect):point cut和advice结合起来就是aspect,它类似于OOP中定义的一个类,但它代表的更多是对象间横向的关系。
·引入(introduce):为对象引入附加的方法或属性,从而达到修改对象结构的目的。有的AOP工具又将其称为mixin。
AOP适用于如下功能:
·安全验证(Authentication )
·缓存(Caching )
·上下文传递(Context passing )
·错误处理(Error handling )
·后期加载(Lazy loading)
·调试(Debugging)
·记录、跟踪、优化和监测(logging,tracing,profiling and monitoring)
·性能优化(Performance optimization)
·持久化(Persistence)
·资源池(Resource pooling)
·同步(Synchronization)
·事务(Transactions)
eg:
//定义接口 package com.greysh.aop.service; public interface HelloWorld { public void say(); } //对应的实现为 package com.greysh.aop.service.impl; import com.greysh.aop.service.HelloWorld; public class HelloWorldImpl implements HelloWorld { public void say() { System.out.println("Say HelloWorld"); } } //程序调用的时候 package com.greysh.aop.test; import com.greysh.aop.factory.ProxyFactory; import com.greysh.aop.service.HelloWorld; import com.greysh.aop.service.impl.HelloWorldImpl; public class TestHelloWorld { public static void main(String[] args) { HelloWorld mb = new HelloWorldImpl(); HelloWorld bi = (HelloWorld) ProxyFactory.getProxy(mb); bi.say(); } } //工厂 package com.greysh.aop.factory; import java.lang.reflect.Proxy; import com.greysh.aop.proxy.ProxyHandler; public class ProxyFactory { public static Object getProxy(Object obj) { ProxyHandler bn = new ProxyHandler(); bn.setTarget(obj); return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),bn); } } //代理和反射类 package com.greysh.aop.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class ProxyHandler implements InvocationHandler { private Object target; public void setTarget(Object target) { this.target = target; } @Override public Object invoke(Object proxy,Method method,Object[] args) throws Throwable { System.out.println("Before Helloworld"); @SuppressWarnings("unused") Object result = method.invoke(target,args); System.out.println("Finish Helloworld"); return null; } } //程序运行时候的结果是 Before Helloworld Say HelloWorld Finish Helloworld 如果不是用AOP,那么打印的结果 Say HelloWorld 这5个文件构成一个最简单的AOP的DEMO 类似Struts2的拦截器 如果两个类实现同一个接口,但是用的时候用一个类代替另一个类,这就是代理模式 上述就用了代理模式 当我们调用bi.say(),其实并不是直接用HelloWorldImpl的say(), 而是 HelloWorld bi = (HelloWorld) ProxyFactory.getProxy(mb); 这样ProxyFactory先用ProxyHandler将对象赋值,这里需要调用reflect包,重写里面的invoke方向,这里的invoke在调用的时候先执行 System.out.println("Before Helloworld"); 然后用反射 Object result = method.invoke(target,args);
控制反转(IOC)和依赖注入(DI)
public class MyBusniessObject{ private DataSource ds; private MyCollaborator myCollaborator; public MyBusnissObject(){ Context ctx = null; try{ ctx = new InitialContext(); ds = (DataSource) ctx.lookup(“java:comp/env/dataSourceName”); myCollaborator = (MyCollaborator) ctx.lookup(“java:comp/env/myCollaboratorName”); }……代码展示了基于 JNDI 实现的依赖查找机制,依赖查找的主要问题是,这段代码必须依赖于JNDI环境,所以它不能在应用服务器之外运行,并且如果要用别的方式取代来查找资源和协作对象,就必须把代码抽出来重构到一个策略方法中去。
package com.senssic; public class Content { public void BusniessContent(){ System.out.println("do business"); } public void AnotherBusniessContent(){ System.out.println("do another business"); } }构造子注入( )
public class MyBusiness { private Content myContent; public MyBusiness(Content content) { myContent = content; } public void doBusiness(){ myContent.BusniessContent(); } public void doAnotherBusiness(){ myContent.AnotherBusniessContent(); } }
public class MyBusiness { private Content myContent; public void setContent(Content content) { myContent = content; } public void doBusiness(){ myContent.BusniessContent(); } public void doAnotherBusiness(){ myContent.AnotherBusniessContent(); } }
设置接口
public interface InContent { void createContent(Content content); }接口注入
public class MyBusiness implements InContent{ private Content myContent; public void createContent(Content content) { myContent = content; } public void doBusniess(){ myContent.BusniessContent(); } public void doAnotherBusniess(){ myContent.AnotherBusniessContent(); } }
spring的事务隔离级别和传播行为
在TransactionDefinition接口中定义了五个不同的事务隔离级别
ISOLATION_DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应
ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读
ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。
ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。