private Invocation next() { if (interceptors.hasNext()) { Interceptor interceptor = interceptors.next(); Object nextInstance = interceptor.getInstance(); Method nextMethod = interceptor.getMethod(); if (nextMethod.getParameterTypes().length == 1 && nextMethod.getParameterTypes()[0] == InvocationContext.class) { return new InterceptorInvocation(nextInstance, nextMethod, this); } else { return new LifecycleInvocation(nextInstance, nextMethod, this, parameters); } } else if (method != null) { // EJB 3.1, it is allowed that timeout method does not have parameter Timer.class, // However, while invoking the timeout method, the timer value is passed, as it is also // required by InnvocationContext.getTimer() method Object[] methodParameters; if (operation.equals(Operation.TIMEOUT) && method.getParameterTypes().length == 0) { methodParameters = new Object[0]; } else { methodParameters = parameters; } return new BeanInvocation(target, method, methodParameters); } else { return new NoOpInvocation(); } }
public Object pluginAll(Object target) { // 循环调用每个Interceptor.plugin方法 for (Interceptor interceptor : interceptors) { target = interceptor.plugin(target); } return target; }
public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable { Object res = null; interceptor.before(); System.out.println("еĴúÂë"); // res=arg1.invoke(object, arg2); interceptor.after(); return res; }
public static void premain(final String agentArgs, Instrumentation instrumentation) throws InstantiationException { counter++; final String callbackId = String.valueOf(counter); try { if (agentArgs == null) { throw new IllegalArgumentException( "Agent argument is required of the form 'interceptor-class-name[;interceptor-custom-args]'"); } String[] tokens = agentArgs.split(";", 2); Class<?> clazz = Agent.class.getClassLoader().loadClass(tokens[0]); final Interceptor interceptor = (Interceptor) clazz.newInstance(); if (tokens.length == 2) { interceptor.init(tokens[1]); } else { interceptor.init(null); } Callback.registerCallback(callbackId, interceptor); instrumentation.addTransformer( new ClassFileTransformer() { public byte[] transform( final ClassLoader loader, final String className, final Class<?> classBeingRedefined, final ProtectionDomain protectionDomain, final byte[] classfileBuffer) throws IllegalClassFormatException { if (!isAncestor(Agent.class.getClassLoader(), loader)) { return classfileBuffer; } return AccessController.doPrivileged( new PrivilegedAction<byte[]>() { public byte[] run() { Instrumentator instrumentator = new Instrumentator(className, classfileBuffer, interceptor, callbackId); return instrumentator.modifyClass(); } }); } }); } catch (Throwable th) { th.printStackTrace(System.err); } }
@Override public void write(int b) throws IOException { _written += 1; boolean complete = _channel.getResponse().isAllContentWritten(_written); // Async or Blocking ? while (true) { switch (_state.get()) { case OPEN: if (_aggregate == null) _aggregate = _channel .getByteBufferPool() .acquire(getBufferSize(), _interceptor.isOptimizedForDirectBuffers()); BufferUtil.append(_aggregate, (byte) b); // Check if all written or full if (complete || BufferUtil.isFull(_aggregate)) { write(_aggregate, complete); if (complete) closed(); } break; case ASYNC: throw new IllegalStateException("isReady() not called"); case READY: if (!_state.compareAndSet(OutputState.READY, OutputState.PENDING)) continue; if (_aggregate == null) _aggregate = _channel .getByteBufferPool() .acquire(getBufferSize(), _interceptor.isOptimizedForDirectBuffers()); BufferUtil.append(_aggregate, (byte) b); // Check if all written or full if (!complete && !BufferUtil.isFull(_aggregate)) { if (!_state.compareAndSet(OutputState.PENDING, OutputState.ASYNC)) throw new IllegalStateException(); return; } // Do the asynchronous writing from the callback new AsyncFlush().iterate(); return; case PENDING: case UNREADY: throw new WritePendingException(); case ERROR: throw new EofException(_onError); case CLOSED: throw new EofException("Closed"); default: throw new IllegalStateException(); } break; } }
@Override public void write(byte[] b, int off, int len) throws IOException { _written += len; boolean complete = _channel.getResponse().isAllContentWritten(_written); // Async or Blocking ? while (true) { switch (_state.get()) { case OPEN: // process blocking below break; case ASYNC: throw new IllegalStateException("isReady() not called"); case READY: if (!_state.compareAndSet(OutputState.READY, OutputState.PENDING)) continue; // Should we aggregate? if (!complete && len <= _commitSize) { if (_aggregate == null) _aggregate = _channel .getByteBufferPool() .acquire(getBufferSize(), _interceptor.isOptimizedForDirectBuffers()); // YES - fill the aggregate with content from the buffer int filled = BufferUtil.fill(_aggregate, b, off, len); // return if we are not complete, not full and filled all the content if (filled == len && !BufferUtil.isFull(_aggregate)) { if (!_state.compareAndSet(OutputState.PENDING, OutputState.ASYNC)) throw new IllegalStateException(); return; } // adjust offset/length off += filled; len -= filled; } // Do the asynchronous writing from the callback new AsyncWrite(b, off, len, complete).iterate(); return; case PENDING: case UNREADY: throw new WritePendingException(); case ERROR: throw new EofException(_onError); case CLOSED: throw new EofException("Closed"); default: throw new IllegalStateException(); } break; } // handle blocking write // Should we aggregate? int capacity = getBufferSize(); if (!complete && len <= _commitSize) { if (_aggregate == null) _aggregate = _channel .getByteBufferPool() .acquire(capacity, _interceptor.isOptimizedForDirectBuffers()); // YES - fill the aggregate with content from the buffer int filled = BufferUtil.fill(_aggregate, b, off, len); // return if we are not complete, not full and filled all the content if (filled == len && !BufferUtil.isFull(_aggregate)) return; // adjust offset/length off += filled; len -= filled; } // flush any content from the aggregate if (BufferUtil.hasContent(_aggregate)) { write(_aggregate, complete && len == 0); // should we fill aggregate again from the buffer? if (len > 0 && !complete && len <= _commitSize && len <= BufferUtil.space(_aggregate)) { BufferUtil.append(_aggregate, b, off, len); return; } } // write any remaining content in the buffer directly if (len > 0) { ByteBuffer wrap = ByteBuffer.wrap(b, off, len); ByteBuffer view = wrap.duplicate(); // write a buffer capacity at a time to avoid JVM pooling large direct buffers // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6210541 while (len > getBufferSize()) { int p = view.position(); int l = p + getBufferSize(); view.limit(p + getBufferSize()); write(view, false); len -= getBufferSize(); view.limit(l + Math.min(len, getBufferSize())); view.position(l); } write(view, complete); } else if (complete) { write(BufferUtil.EMPTY_BUFFER, true); } if (complete) closed(); }
protected void write(ByteBuffer content, boolean complete, Callback callback) { _interceptor.write(content, complete, callback); }
@Override protected void checkedRun() { if (Debug.THREADS) { ThreadAssert.resume(this, false); ThreadAssert.exchangeTake(this); } Exception ex; try { onRunStarting(); runTasks(); // while (_inserts.size() > 0) _refs.add(writeObject(_inserts.poll())); // if (Debug.ENABLED) Debug.assertion(!_writer.interrupted()); for (;;) { BinaryStore.this.run(_writer); if (!_writer.interrupted()) break; _writer.grow(); } _writer.writeSnapshots(); // Exception wrongStore = null; int toremove; if (_writer.getWrongStore() == null) _jdbm.commit(); else { _jdbm.rollback(); wrongStore = new RuntimeException(Strings.WRONG_STORE + _writer.getWrongStore()); } while (_processed.size() > 0) { Transaction branch = _processed.pollPartOfClear(); byte interception = _processedInterceptions[_processed.size()]; if (wrongStore == null) Interceptor.ack(branch, interception, true); else Interceptor.nack(branch, null, wrongStore); } if (wrongStore != null) { if (Debug.ENABLED) { // Assert old records have been restored on rollback for (int i = 0; i < _updatedVersions.size(); i++) { Version shared = _updatedVersions.get(i); Debug.assertion(_jdbm.fetch(shared.getRecord()) != null); } } _updatedVersions.clear(); _updatedSessions.clear(); } else { while (_updatedVersions.size() > 0) { Version shared = _updatedVersions.pollPartOfClear(); long record = _updatedVersionsRecords[_updatedVersions.size()]; shared.setRecord(record); } while (_updatedSessions.size() > 0) { Session session = _updatedSessions.pollPartOfClear(); long records = _updatedSessionsRecords[_updatedSessions.size()]; session.setRecords(records); } } // while (_callbacks.size() > 0) { AsyncCallback<byte[]> callback = _callbacks.poll(); byte[] ref = _refs.poll(); if (wrongStore == null) callback.onSuccess(ref); else callback.onFailure(wrongStore); } // _writer.resetWrongStore(); if (Debug.THREADS) ThreadAssert.suspend(this); setFlushes(); onRunEnded(); return; } catch (Exception e) { ex = e; } while (_callbacks.size() > 0) _callbacks.poll().onFailure(ex); // Only in case of exception (can be closing) onException(ex); }