001/*
002 * Copyright 2002-2012 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.jmx.access;
018
019import org.springframework.aop.framework.ProxyFactory;
020import org.springframework.beans.factory.BeanClassLoaderAware;
021import org.springframework.beans.factory.FactoryBean;
022import org.springframework.beans.factory.InitializingBean;
023import org.springframework.jmx.MBeanServerNotFoundException;
024import org.springframework.util.ClassUtils;
025
026/**
027 * Creates a proxy to a managed resource running either locally or remotely.
028 * The "proxyInterface" property defines the interface that the generated
029 * proxy is supposed to implement. This interface should define methods and
030 * properties that correspond to operations and attributes in the management
031 * interface of the resource you wish to proxy.
032 *
033 * <p>There is no need for the managed resource to implement the proxy interface,
034 * although you may find it convenient to do. It is not required that every
035 * operation and attribute in the management interface is matched by a
036 * corresponding property or method in the proxy interface.
037 *
038 * <p>Attempting to invoke or access any method or property on the proxy
039 * interface that does not correspond to the management interface will lead
040 * to an {@code InvalidInvocationException}.
041 *
042 * @author Rob Harrop
043 * @author Juergen Hoeller
044 * @since 1.2
045 * @see MBeanClientInterceptor
046 * @see InvalidInvocationException
047 */
048public class MBeanProxyFactoryBean extends MBeanClientInterceptor
049                implements FactoryBean<Object>, BeanClassLoaderAware, InitializingBean {
050
051        private Class<?> proxyInterface;
052
053        private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
054
055        private Object mbeanProxy;
056
057
058        /**
059         * Set the interface that the generated proxy will implement.
060         * <p>This will usually be a management interface that matches the target MBean,
061         * exposing bean property setters and getters for MBean attributes and
062         * conventional Java methods for MBean operations.
063         * @see #setObjectName
064         */
065        public void setProxyInterface(Class<?> proxyInterface) {
066                this.proxyInterface = proxyInterface;
067        }
068
069        @Override
070        public void setBeanClassLoader(ClassLoader classLoader) {
071                this.beanClassLoader = classLoader;
072        }
073
074        /**
075         * Checks that the {@code proxyInterface} has been specified and then
076         * generates the proxy for the target MBean.
077         */
078        @Override
079        public void afterPropertiesSet() throws MBeanServerNotFoundException, MBeanInfoRetrievalException {
080                super.afterPropertiesSet();
081
082                if (this.proxyInterface == null) {
083                        this.proxyInterface = getManagementInterface();
084                        if (this.proxyInterface == null) {
085                                throw new IllegalArgumentException("Property 'proxyInterface' or 'managementInterface' is required");
086                        }
087                }
088                else {
089                        if (getManagementInterface() == null) {
090                                setManagementInterface(this.proxyInterface);
091                        }
092                }
093                this.mbeanProxy = new ProxyFactory(this.proxyInterface, this).getProxy(this.beanClassLoader);
094        }
095
096
097        @Override
098        public Object getObject() {
099                return this.mbeanProxy;
100        }
101
102        @Override
103        public Class<?> getObjectType() {
104                return this.proxyInterface;
105        }
106
107        @Override
108        public boolean isSingleton() {
109                return true;
110        }
111
112}