001/* 002 * Copyright 2002-2016 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.export.assembler; 018 019import java.lang.reflect.Method; 020import java.util.Arrays; 021import java.util.Enumeration; 022import java.util.HashMap; 023import java.util.HashSet; 024import java.util.Map; 025import java.util.Properties; 026import java.util.Set; 027 028import org.springframework.util.StringUtils; 029 030/** 031 * Subclass of {@code AbstractReflectiveMBeanInfoAssembler} that allows 032 * to specify method names to be exposed as MBean operations and attributes. 033 * JavaBean getters and setters will automatically be exposed as JMX attributes. 034 * 035 * <p>You can supply an array of method names via the {@code managedMethods} 036 * property. If you have multiple beans and you wish each bean to use a different 037 * set of method names, then you can map bean keys (that is the name used to pass 038 * the bean to the {@code MBeanExporter}) to a list of method names using the 039 * {@code methodMappings} property. 040 * 041 * <p>If you specify values for both {@code methodMappings} and 042 * {@code managedMethods}, Spring will attempt to find method names in the 043 * mappings first. If no method names for the bean are found, it will use the 044 * method names defined by {@code managedMethods}. 045 * 046 * @author Juergen Hoeller 047 * @since 1.2 048 * @see #setManagedMethods 049 * @see #setMethodMappings 050 * @see InterfaceBasedMBeanInfoAssembler 051 * @see SimpleReflectiveMBeanInfoAssembler 052 * @see MethodExclusionMBeanInfoAssembler 053 * @see org.springframework.jmx.export.MBeanExporter 054 */ 055public class MethodNameBasedMBeanInfoAssembler extends AbstractConfigurableMBeanInfoAssembler { 056 057 /** 058 * Stores the set of method names to use for creating the management interface. 059 */ 060 private Set<String> managedMethods; 061 062 /** 063 * Stores the mappings of bean keys to an array of method names. 064 */ 065 private Map<String, Set<String>> methodMappings; 066 067 068 /** 069 * Set the array of method names to use for creating the management info. 070 * These method names will be used for a bean if no entry corresponding to 071 * that bean is found in the {@code methodMappings} property. 072 * @param methodNames an array of method names indicating the methods to use 073 * @see #setMethodMappings 074 */ 075 public void setManagedMethods(String... methodNames) { 076 this.managedMethods = new HashSet<String>(Arrays.asList(methodNames)); 077 } 078 079 /** 080 * Set the mappings of bean keys to a comma-separated list of method names. 081 * The property key should match the bean key and the property value should match 082 * the list of method names. When searching for method names for a bean, Spring 083 * will check these mappings first. 084 * @param mappings the mappins of bean keys to method names 085 */ 086 public void setMethodMappings(Properties mappings) { 087 this.methodMappings = new HashMap<String, Set<String>>(); 088 for (Enumeration<?> en = mappings.keys(); en.hasMoreElements();) { 089 String beanKey = (String) en.nextElement(); 090 String[] methodNames = StringUtils.commaDelimitedListToStringArray(mappings.getProperty(beanKey)); 091 this.methodMappings.put(beanKey, new HashSet<String>(Arrays.asList(methodNames))); 092 } 093 } 094 095 096 @Override 097 protected boolean includeReadAttribute(Method method, String beanKey) { 098 return isMatch(method, beanKey); 099 } 100 101 @Override 102 protected boolean includeWriteAttribute(Method method, String beanKey) { 103 return isMatch(method, beanKey); 104 } 105 106 @Override 107 protected boolean includeOperation(Method method, String beanKey) { 108 return isMatch(method, beanKey); 109 } 110 111 protected boolean isMatch(Method method, String beanKey) { 112 if (this.methodMappings != null) { 113 Set<String> methodNames = this.methodMappings.get(beanKey); 114 if (methodNames != null) { 115 return methodNames.contains(method.getName()); 116 } 117 } 118 return (this.managedMethods != null && this.managedMethods.contains(method.getName())); 119 } 120 121}