public interface ISubject {
public void request();
}
public class RealSubject implements ISubject{
@Override
public void request() {
System.out.println("this is do request");
}
}
public class RequestHandler implements InvocationHandler {
private ISubject target;
public RequestHandler(ISubject target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("request")) {
System.out.println("dynamic proxy do some thing");
}
return method.invoke(target, args);
}
}
public class Demo {
public static void main(String[] args) {
ISubject target = new RealSubject();
ISubject subject = (ISubject)Proxy.newProxyInstance(target.getClass().getClassLoader(),
new Class[] {ISubject.class},
new RequestHandler(target));
subject.request();
}
}
Spring AOP会在代理对象的拦截器中,织入各种横切逻辑。Spring AOP给出了一系列Advice横切实现,比如BeforeAdvice(前置通知)、AfterAdvice(后置通知)、ThrowsAdvice(异常通知等)异常通知等。Spring AOP还提供了一系列的Pointcut来匹配切入点。Spring AOP中还设计了一系列Adapter,各个Adapter会匹配Advice和其特定的拦截器,实现各种Advice织入。
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class[] additionalInterfaces = rootClass.getInterfaces();
for (Class additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class[] types = new Class[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
//获得目标对象
target = targetSource.getTarget();
Class targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method.
//获得定义好的拦截器链
List
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
//获得目标对象
target = targetSource.getTarget();
Class targetClass = (target != null ? target.getClass() : null);
//获得定义好的拦截器链
List
public List getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
//获取一个AdvisorAdapterRegistry实例
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
//获得通知器链,这个通知器链可以在bean文件中配置,也可以通过代码手动添加。
Advisor[] advisors = config.getAdvisors();
List interceptorList = new ArrayList<>(advisors.length);
Class actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
//遍历通知器链
for (Advisor advisor : advisors) {
//如果通知器是PointcutAdvisor类型的
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
//判断是否已经进行了预筛选的匹配操作或者进行类型级别匹配织入操作
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
//进行方法级别匹配被执行织入操作
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
//如果有匹配的通知器
if (match) {
//通过AdvisorAdapterRegistry实例,来获取通知器的拦截器链
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
//如果通知器是IntroductionAdvisor类型的
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
//判断是否已经进行了预筛选的匹配操作或者进行类型级别匹配织入操作
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
//通过AdvisorAdapterRegistry实例,来获取通知器的拦截器链
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
//通过AdvisorAdapterRegistry实例,来获取通知器的拦截器链
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
以上代码其实主要做了三件事情:
获得通知器链。
根据通知器的类型来进行类型和方法级别的匹配。
通过AdvisorAdapterRegistry实例来获取通知器上对应的拦截器。
3.1.1获得通知器链
Spring AOP中是通过调用了AdvisedSupport对象的getAdvisors方法来获取获得通知器链的。这个通知器链在获取代理对象前就已经完成了初始化。
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
//定义了一个AdvisorAdapter类型的List
private final List adapters = new ArrayList<>(3);
//在构造函数中注册MethodBeforeAdviceAdapter,AfterReturningAdviceAdapter,ThrowsAdviceAdapter三个适配器。
//这三个适配器分别对应了MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice三个通知
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
//将advice通知包装成Advisor通知器
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
//通过通知器来获取通知器所对应的拦截器数组
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List interceptors = new ArrayList<>(3);
//从advisor通知器获取到对应的advicer通知
Advice advice = advisor.getAdvice();
//如果通知advice是MethodInterceptor类型的,则直接加入到interceptors的列表
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
//循环所有已注册的adapter(MethodBeforeAdviceAdapter,AfterReturningAdviceAdapter,ThrowsAdviceAdapter)
for (AdvisorAdapter adapter : this.adapters) {
//如果这个advice通知是当前adapter所支持的类型
if (adapter.supportsAdvice(advice)) {
//对advisor通知器进行适配,从adapter中取出对应封装好AOP编织功能的拦截器
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
//把适配器注册到AdvisorAdapter类型的List中
@Override
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}
Spring AOP在JDK动态代理中,生成的MethodInvocation实例ReflectiveMethodInvocation对象。而通过CGLIB产生的MethodInvocation实例是CglibMethodInvocation对象。CglibMethodInvocation是ReflectiveMethodInvocation的子类。它们对拦截器链的调用都是在ReflectiveMethodInvocation中通过proceed方法来实现的。
下面我们来研究下ReflectiveMethodInvocation的proceed方法代码
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
//通过索引来判断拦截器列表中的拦截器是否已经全部调用完毕。
// 如果调用完毕,则通过反射机制来调用目标对象的方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
//通过索引递增,来获取列表中的拦截器。索引是从-1开始。
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//如果拦截器是否是InterceptorAndDynamicMethodMatcher类型的
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
//进行方法动态匹配的判断,若匹配,就执行advice通知的横切逻辑
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
//不匹配的话,递归调用proceed方法
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
//如果是一个MethodInterceptor类型的拦截器,则直接调用这个拦截器的invoke方法。
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
Spring AOP会根据@AspectJ注解来查找相关的Aspect定义,并将其声明的横切逻辑织入到当前系统中。其实就是把以前在xml中定义的通知和切点,现在放到了具有特定注解的POJO对象中,但是@AspectJ方式的最终的实现机制还是Spring AOP最初的架构,也就是使用代理模式处理横切逻辑的织入。
public List buildAspectJAdvisors() {
List aspectNames = this.aspectBeanNames;
//判断@Aspect注解缓存的beanName列表是否为空。
//容器中@Aspect注解的beanName和这个Bean中定义的通知器,只会第一次获取后放入缓存,以后只从缓存中取。
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
//获取Spring容器中所有Bean的名称
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//循环遍历所有的Bean名称
for (String beanName : beanNames) {
//判断是否是合法的Bean,不合法则跳过循环。默认返回true,由其子类定义规则。
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
//通过Bean名称来获取到相应的Bean的类型
Class beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
//通过Bean的类型来判断这个Bean是否有@Aspect的注解
if (this.advisorFactory.isAspect(beanType)) {
//如果是@Aspect注解的Bean,则把Bean的名称假如缓存
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//获取到@Aspect注解的Bean定义的通知器
List classAdvisors = this.advisorFactory.getAdvisors(factory);
//将获取到的通知器加入到缓存中
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
//获取到@Aspect注解的Bean定义的通知器,并加入到通知器的列表
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
//Spring容器中,没有@Aspect的注解Bean的情况
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
//如果通知器已经缓存,则按BeanName从缓存中获取通知器
List advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
GetUrlParam:function GetUrlParam(param){
var reg = new RegExp("(^|&)"+ param +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null
==================================================
1、打开PowerDesigner12,在菜单中按照如下方式进行操作
file->Reverse Engineer->DataBase
点击后,弹出 New Physical Data Model 的对话框
2、在General选项卡中
Model name:模板名字,自
网站配置是apache+tomcat,tomcat没有报错,apache报错是:
The proxy server received an invalid response from an upstream server. The proxy server could not handle the request GET /. Reason: Error reading fr
Free variable A free variable of an expression is a variable that’s used inside the expression but not defined inside the expression. For instance, in the function literal expression (x: Int) => (x
Part Ⅰ:
《阿甘正传》Forrest Gump经典中英文对白
Forrest: Hello! My names Forrest. Forrest Gump. You wanna Chocolate? I could eat about a million and a half othese. My momma always said life was like a box ochocol
Json在数据传输中很好用,原因是JSON 比 XML 更小、更快,更易解析。
在Java程序中,如何使用处理JSON,现在有很多工具可以处理,比较流行常用的是google的gson和alibaba的fastjson,具体使用如下:
1、读取json然后处理
class ReadJSON
{
public static void main(String[] args)