public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
//如果需要封装的对象---是---Advisor类型就不需要处理
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
//此方法值对Advisor和Advice类型两种数据进行封装,如果不知就不能封装
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
//如果需要封装的对象---是---MethodInterceptor类型,则使用DefaultPointcutAdvisor不需要适配
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
//如果是Advisor的适配器那么也同样需要进行封装
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
//检查是否是支持适配的类型
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
当proxyFactory初始化之后就是进行代理的创建了
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
//active这个值的作用是在创建第一个AOP代理时设置为true,并告诉对应的监听器第一个AOP在创建
if (!this.active) {
activate();
}
//创建代理
return getAopProxyFactory().createAopProxy(this);
}
&esmp;接下来就是进行代理的创建
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//在这里判断代理的设置属性,
//optimize:代理是否应该执行积极的优化,默认为false
//proxyTargetClass:是否直接代理目标类以及任何接口
//hasNoUserSuppliedProxyInterfaces: 判断是否又用户提供的代理接口
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.");
}
//如果需要代理的类是接口则使用jdk代理
if (targetClass.isInterface()) {
return new JdkDynamicAopProxy(config);
}
//使用cglib代理方式
return CglibProxyFactory.createCglibProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class> targetClass = null;
Object target = null;
try {
//如果没有在代理接口中定义equal方法,并且代理的方法是equals方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
//同上是对hashCode方法的处理
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
//如果代理方法是接口中的方法并且方法是Advised相同的类或者接口则进行处理
//Class类的isAssignableFrom(Class cls)表示如果调用这个方法的class或接口 与参数cls表示的类或接口相同,或者是
//参数cls表示的类或接口的父类,则返回true
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;
//如果目标对象存在内部的自我调用,则需要暴露代理
//exposeProxy: 设置代理是否应该由AOP框架作为ThreadLocal公开,以便通过AopContext类进行检索。如果建议的对象需要自己调用另一个建议的方法,这将非常有用
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null. Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
// Get the interception chain for this method.
//获取当前方法的连接器链
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
//如果不存在任何拦截器,则直接进行切点方法的调用
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
else {
// We need to create a method invocation...
//将拦截器链封装在ReflectiveMethodInvocation对象中,以便使用proceed方法调用
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
//执行拦截方法
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class> returnType = method.getReturnType();
//返回结果
if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
现在对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();
}
//获取下一个需要执行的拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//如果拦截器是InterceptorAndDynamicMethodMatcher(内部框架类,将MethodInterceptor实例与MethodMatcher组合,用作顾问程序链中的元素)类型的
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
//对对应的方法和目标类以及参数进行匹配,如果匹配上则执行拦截方法,不匹配则不执行,调用下一个拦截器
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
//如果是普通的拦截器,所以我们只是调用它。普通的拦截器有:ExposeInvocationInterceptor,DelegatingIntroductionInterceptor,MethodBeforeAdviceInterceptor,AspectJAroundAdvice,AspectJAfterThrowingAdvice,AspectJAfterAdvice等
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
例如,你想myuser使用mypassword从任何主机连接到mysql服务器的话。
GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%'IDENTIFIED BY 'mypassword' WI
TH GRANT OPTION;
如果你想允许用户myuser从ip为192.168.1.6的主机连接到mysql服务器,并使用mypassword作
在 Service Pack 4 (SP 4), 是运行 Microsoft Windows Server 2003、 Microsoft Windows Storage Server 2003 或 Microsoft Windows 2000 服务器上您尝试安装 Microsoft SQL Server 2000 通过卷许可协议 (VLA) 媒体。 这样做, 收到以下错误信息CD KEY的 SQ
OS 7 has a new method that allows you to draw a view hierarchy into the current graphics context. This can be used to get an UIImage very fast.
I implemented a category method on UIView to get the vi
方法一:
在my.ini的[mysqld]字段加入:
skip-grant-tables
重启mysql服务,这时的mysql不需要密码即可登录数据库
然后进入mysql
mysql>use mysql;
mysql>更新 user set password=password('新密码') WHERE User='root';
mysq
背景
2014年11月12日,ASP.NET之父、微软云计算与企业级产品工程部执行副总裁Scott Guthrie,在Connect全球开发者在线会议上宣布,微软将开源全部.NET核心运行时,并将.NET 扩展为可在 Linux 和 Mac OS 平台上运行。.NET核心运行时将基于MIT开源许可协议发布,其中将包括执行.NET代码所需的一切项目——CLR、JIT编译器、垃圾收集器(GC)和核心