JMX
์คํ๋ง์ DI๋ ๋น ํ๋กํผํฐ๋ฅผ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ค ํ๋์ด๋ค. ๊ทธ๋ฌ๋ ์ผ๋จ ๋ฐฐํฌ๊ฐ ๋ผ์ ์คํ์ค์ด๋ฉด, DI๋ง์ผ๋ก๋ ์ค์ ์ ๋ณ๊ฒฝํ ์ ์๋ค.
* ์ด ๋ ์คํ์ค์ธ ์ฑ์ ์ค์ ์ ๋ฐ๊พธ๊ธฐ ์ํด, JMX(Java Management Extenstison)์ ์ฌ์ฉํ ์ ์๋ค.
๊ด๋ฆฌ๋น(Management Bean, ์ดํ MBean) : JMX๋ฅผ ์ด์ฉํ ๊ด๋ฆฌ ๋ชฉ์ ์ ํนํ๋์ด ์๋ ๊ตฌ์ฑ์์. ๊ด๋ฆฌ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ๋ ๋ฉ์๋๋ฅผ ๋ ธ์ถํ๋ ์๋ฐ ๋น => ๋ค๊ฐ์ง ํ์ ์ MBean์ด ์ ์
ํ์ค MBean : ๊ณ ์ ๋ ์๋ฐ ์ธํฐํ์ด์ค์ ๋ฆฌํ๋ ์ ์ ์ํด ๊ด๋ฆฌ ์ธํฐํ์ด์ค๊ฐ, ๊ฒฐ์ ๋๋ MBean
๋์ MBean : ์คํ์์ DynamicMBean ์ธํฐํ์ด์ค์ ๋ฉ์๋ ํธ์ถ์ ์ํด ๊ด๋ฆฌ ์ธํฐํ์ด์ค๊ฐ ๊ฒฐ์ , ์คํ์๋ง๋ค ๋ฌ๋ผ์ง ์ ์์
์คํ MBean : ํน๋ณํ ๋์ MBean์ผ๋ก, ์ ํธ๋ฆฌ๋ทฐํธ์ ์คํผ๋ ์ด์ ์ด ํ๋ฆฌ๋ฏธํฐ๋ธ ํ์ , ํ๋ฆฌ๋ฏธํฐ๋ธ ํ์ ์ฉ ํด๋์ค ๋ํผ, ํ๋ฆฌ๋ฏธํฐ๋ธ๋ ํ๋ฆฌ๋ฏธํฐ๋ ๋ํผ๋ก ๋ถํด๋ ์ ์๋ ํ์ ์ผ๋ก ์ ํ
๋ชจ๋ธ MBean : ๊ด๋ฆฌ ์ธํฐํ์ด์ค๋ฅผ ๊ด๋ฆฌ ๋ฆฌ์์ค๋ก ๋๊ธฐ๋ ํน์ดํ ๋์ MBean. ์ ์ธ๋๋๋งํผ ์์ฑ๋์ง๋ ์์. ์ผ๋ฐ์ ์ผ๋ก ๋ฉํ์ ๋ณด๋ฅผ ์ด์ฉํ์ฌ ๊ด๋ฆฌ ์ธํฐํ์ด์ค๋ฅผ ์กฐ๋ฆฝํ๋ ํฉํ ๋ฆฌ์ ์ํด ๋ง๋ค์ด์ง
=> ์คํ๋ง์ JMX ๋ชจ๋์ ์ด์ฉํ์ฌ, ์คํ๋ง ์ ํ๋ฆฌ์ผ์ด์ ์ ๋น์ ๊ด๋ฆฌํ ์ ์๋ค
1 ์คํ๋ง ๋น์ MBean์ผ๋ก ์ต์คํฌํธํ๊ธฐ
JMX๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด, ํ๋กํผํฐ๋ฅผ ์ถ๊ฐ
public static final int DEFAULT_SPITTLES_PER_PAGE = 25; // ์คํ์์ ์ ๋ณ๊ฒฝํ ํ๋กํผํฐ
private int spittlesPerPage = DEFAULT_SPITTLES_PER_PAGE;
public void setSpittlesPerPage(int spittlesPerPage) { // ๋น๋ ์์ ์ JMX๋ฅผ ์ด์ฉํ์ฌ ์คํํ ๋ฉ์๋
this.spittlesPerPage = spittlesPerPage;
}
public int getSpittlesPerPage() {
return spittlesPerPage;
}
=> ์ด๊ฒ๋ง์ผ๋ก, ์ธ๋ถ์์ ์ค์ ์ ๋ถ๊ฐ๋ฅ, ๋ค๋ฅธ ํ๋กํผํฐ์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋น์ ํ๋กํผํฐ์ผ ๋ฟ
=> Controller ๋น์, MBean์ผ๋ก ๋ ธ์ถํด์ผ ํจ => ๊ทธ๋ฌ๋ฉด ํ๋กํผํฐ๊ฐ ๊ด๋ฆฌ ์ ํธ๋ฆฌ๋ทฐํธ๋ก ๋ ธ์ถ
// MBeanExporter๋ก, MBean ์๋ฒ์์ ์คํ๋ง ๊ด๋ฆฌ ๋น์, ๋ชจ๋ธMBean์ผ๋ก ์ต์คํฌํธ
@Bean
public MBeanExporter mbeanExporter(SpittleController spittleController) {
MBeanExporter exporter = new MBeanExporter();
Map<String, Object> beans = new HashMap<String, Object>();
beans.put("spitter:name=SpittleController", spittleController); // Cotroller๋ฅผ, MBean์ผ๋ก ๋
ธ์ถ
exporter.setBeans(beans);
return exporter;
}
==> ์ด ๊ฒฝ์ฐ์ MBean - pair.spitter:name=SpittleController


=> MBeanExporter ์ค์ ํ, SpittleController๊ฐ ๊ด๋ฆฌ ์๋ฒ์ ๋ชจ๋ธMBean์ผ๋ก ์ต์คํฌํธ ๋จ. ๋ชจ๋ public ๋ฉค๋ฒ๋ MBean ์คํผ๋ ์ด์ ๊ณผ ์ ํธ๋ฆฌ๋ทฐํธ๋ก ์ต์คํฌํธ.
=> ํ์ง๋ง spittlesPerPage ํ๋กํผํฐ ์ค์ ์ ์ ์ธํ๊ณ ๋, ๊ตณ์ด ๋ค๋ฅธ ๋ถ๋ถ์ ๋ณผ ํ์๊ฐ ์๋ค(spittles, getSpittlesPerPage emd)
=> ์ด๋ฌํ MBean์ ์ ํธ๋ฆฌ๋ทฐํธ์ ์คํ๋ ์ด์ ์ ์ด๋ฅผ ์ํ ๋ช๊ฐ์ง ์ต์ ์ด ์์
์ด๋ฆ์ ์ฌ์ฉํ์ฌ ๋ ธ์ถ, ๋ฌด์ํ๋ ๋น ๋ฉ์๋ ์ ์ธ
์ธํฐํ์ด์ค๋ก ๊ตฌ์ฑํ์ฌ ๋ ธ์ถ ๋ฉ์๋ ์ ํ
๋น์ ์ ๋ํ ์ด์ ์ ์ ์ฉํ์ฌ ๊ด๋ฆฌ ์ ํธ๋ฆฌ๋ทฐํธ์ ์คํผ๋ ์ด์ ์ง์
1.1 ์ด๋ฆ์ผ๋ก ๋ฉ์๋ ๋
ธ์ถ์ํค๊ธฐ
MBean ์ธํฌ ์ด์ ๋ธ๋ฌ : MBean์์ ์ต์คํฌํธ ์ํฌ ์คํผ๋ ์ด์ ๊ณผ, ์ ํธ๋ฆฌ๋ทฐํธ๋ฅผ ์ ํํ๋๋ฐ ํต์ฌ์ ์ธ ์ญํ
=> MethoodNameBasedMBeanInfoAssembler
์๋ฐ๋น ๊ท์น์ ์ํด, spittlesPerPage ํ๋กํผํฐ๋ set~(์ค์ ์), get~(์ ๊ทผ์)๋ฅผ ๊ฐ์ง, MBean์ ๋ ธ์ถ์ ์ ํํ๊ธฐ์ํด, ์ด์ ๋ธ๋ฌ์๊ฒ ์ธํฐํ์ด์ค์ ์๋๋ฉ์๋๋ง ํฌํจํ๋ผ๊ณ ์๋ ค์ฃผ์ด์ผ ํจ
// ์ด์
๋ธ๋ฌ์, ๊ด๋ฆฌํ ๋ฉ์๋๋ง ๋ฑ๋ก(set,get)
@Bean
public MethodNameBasedMBeanInfoAssembler assembler() {
MethodNameBasedMBeanInfoAssembler assembler = new MethodNameBasedMBeanInfoAssembler();
assembler.setManagedMethods(new String[] {"getSpittlesPerPage", "setSpittlesPerPage" }); // ๊ด๋ฆฌํ ๋ฉ์๋๋ฅผ ์ ํ
return assembler;
}
// ์ต์คํฌํฐ์, ํด๋น ์ด์
๋ธ๋ฌ ๋ฑ๋ก
@Bean
public MBeanExporter mbeanExporter(SpittleController spittleController, MBeanInfoAssembler assembler) {
MBeanExporter exporter = new MBeanExporter();
Map<String, Object> beans = new HashMap<String, Object>();
beans.put("spitter:name=SpittleController", spittleController);
exporter.setBeans(beans);
exporter.setAssembler(assembler); // ์ด์
๋ธ๋ฌ ๋ฑ๋ก
return exporter;
}
=> ์ ์ฌ์ง์ ์๋ spittles()๊ฐ ๋ ธ์ถ๋์ง ์๊ฒ ๋๋ค.

* ๋ ๋ค๋ฅธ ๋ฉ์๋ ์ด๋ฆ ๊ธฐ๋ฐ ์ด์ ๋ธ๋ฌ๋ก๋, MethodExclusionMBeanInfoAssembler๊ฐ ์์
=> ์์ MethodNamedBasedMBeanInfoAssembler์๋ ๋ฐ๋๋ก, ๋๋ฌ๋ด์ง ์๋ ๋ฉ์๋์ ๋ชฉ๋ก์ ๋ถ์ฌํจ
@Bean
public MethodExclusionMBeanInfoAssembler assembler() {
MethodExclusionMBeanInfoAssembler assembler = new MethodExclusionMBeanInfoAssembler();
assembler.setIgnoredMethods(new String[] {"spittles"});
return assembler;
}
* ๋์์ ์์ ์ฌ์ง๊ณผ ๊ฐ๋ค(spittles๋ฅผ ์ ํํ๊ธฐ ๋๋ฌธ)
1.2 ์ธํฐํ์ด์ค๋ฅผ ์ด์ฉํ MBean ์คํผ๋ ์ด์
๊ณผ ์ ํธ๋ฆฌ๋ทฐํธ ์ ์
InrterfaceBasedMeanInfoAssembler๋, ์ธํฐํ์ด์ค๋ฅผ ์ด์ฉํด MBean ๊ด๋ฆฌ ์คํผ๋ ์ด์ ์ผ๋ก ์ต์คํฌํธํ ๋น์ ๋ฉ์๋๋ฅผ ์ ํํ๋ ์ด์ ๋ธ๋ฌ, ์ธํฐํ์ด์ค๋ฅผ ๋์ดํ๋ค๋ ์ ์ ์ธํ๊ณ ๋ MethodNamedBasedMBeanInfoAssembler์ ์ ์ฌํ๋ค
// ์ธํฐํ์ด์ค
public interface SpittleControllerManagedOperations {
int getSpittlesPerPage();
void setSpittlesPerPage(int spittlesPerPage);
}
// ์ธํฐํ์ด์ค ๊ธฐ๋ฐ์ ์ด์
๋ธ๋ฌ => ์์ ์ธํฐํ์ด์ค๋ฅผ ๊ด๋ฆฌํ๊ฒ ์ค์
@Bean
public InterfaceBasedMBeanInfoAssembler assembler() {
InterfaceBasedMBeanInfoAssembler assembler = new InterfaceBasedMBeanInfoAssembler();
assembler.setManagedInterfaces(new Class<?>[] { SpittleControllerManagedOperations.class });
return assembler;
}
* ์ธํฐํ์ด์ค๋ฅผ ๊ธฐ์ค์ผ๋ก, MBean์ ๊ด๋ฆฌํ ์ ์๊ฒ ๋๋ค.
* ์ธํฐํ์ด์ค๋ก ๊ด๋ฆฌ๋ฅผ ํ๋ฉด, ์์ญ ๊ฐ์ ๋ฉ์๋๋ ๋ช ๊ฐ์ ์ธํฐํ์ด์ค๋ก ํฉ์น ์ ์์ผ๋ฉฐ, ๋ณต์์ MBean์ ์ต์คํฌํธํ๋ ๊ฒฝ์ฐ์๋ ์คํ๋ง ์ค์ ์ด ๊น๋ํ๊ฒ ์ ์ง๋๋ค
* ๊ทธ๋ฌ๋, ๊ด๋ฆฌ ์คํผ๋ ์ด์ ์ ์ ์ธ์ ์ฝ๋์์ ์ค๋ณต์ผ๋ก ๋ํ๋๋ค(๋จ์ํ MBeanExporter๋ฅผ ์ํด) => ์ด์ ๊ฐ์ ์ค๋ณต์ ์ ๊ฑฐํ๋ ๋ฐฉ๋ฒ์ ์ ๋ํ ์ด์ ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค
1.3 ์ ๋ํ
์ด์
์ฃผ๋์ MBean์ ์ด์ฉํ ์์
MetadataMBeanIfoAssembler : ์ ๋ํ ์ด์ ์ ์ด์ฉํด, ์คํผ๋ ์ด์ ๊ณผ ์ ํธ๋ฆฌ๋ทฐํธ๋ฅผ ์ค์ ํ ์ ์๋ ์ธํฌ ์ด์ ๋ธ๋ฌ
=> ํด๋น ์ด์ ๋ธ๋ฌ๋ฅผ ์๋์ผ๋ก ์์ด์ด๋ง ํ๋ ์์ ์ ๋ถ๋ด์ค๋ฝ๊ณ , ๋จ์ง ์ ๋ํ ์ด์ ์ ์ํด ๊ทธ๋ฐ ์์ ์ ํ ํ์๊ฐ ์์
=> ๊ฐ๋จํ ๋ฐฉ๋ฒ ์ ๊ณต, context ์ค์ ๋ค์์คํ์ด์ค์ด์ฉ(์ฌ์ฉํ๋ MBeanExporter๋์ )
<context:mbean-export server="mbeanServer" />
=> ์ด์ ์คํ๋ง ๋น์ ๋ณํ, @ManagedResource๋ฅผ ์ ์ฉํ๊ณ , ๋ฉ์๋๋ @ManagedOperation, @ManagedAttribute ์ ์ฉ
@Controller
@ManagedResource(objectName="spitter:name=SpittleController") // MBean์ผ๋ก ์ต์คํฌํธ
public class SpittleController {
@ManagedAttribute // ๊ด๋ฆฌ ์ ํธ๋ฆฌ๋ทฐํธ
public void setSpittlesPerPage(int spittlesPerPage) {
this.spittlesPerPage = spittlesPerPage;
}
@ManagedAttribute // ๊ด๋ฆฌ ์ ํธ๋ฆฌ๋ทฐํธ
public int getSpittlesPerPage() {
return spittlesPerPage;
}
}
=> @ManagedAttribute๋ฅผ get์๋ค๋ง ์ ์ฉํ๋ฉด, JMX์์ spittlePerPage๋ ์ฝ๊ธฐ์ ์ฉ ํ๋กํผํฐ๊ฐ ๋จ
=> @ManagedAttribute๋ฅผ ์ ์ฉํ๋ฉด, spittlePerPage ํ๋กํผํฐ๋, ๊ด๋ฆฌ ์ ํธ๋ฆฌ๋ทฐํธ๋ก ๋ ธ์ถ์ํด => ๋ง์ฝ ํ๋กํผํฐ ์์ฒด(spittlesPerPage)๋ฅผ ๋ ธ์ถ์ํค๊ณ ์ถ์ง ์๋ค๋ฉด, @ManagedOPeration ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๋ค
1.4 MBean ์ถฉ๋ ์ฒ๋ฆฌ
* ๋ง์ฝ ๊ฐ์ ์ด๋ฆ์ MBean์ด ์ด๋ฏธ ์กด์ฌํ์ฌ, ์ถฉ๋์ด ๋ฐ์ํ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น? => ๊ธฐ๋ณธ์ ์ผ๋ก, MBeanExporter๋ InstanceAlreadyExistException์ ๋์ง
=> ํ์ง๋ง, ์ต์คํฌํฐ์ registrationBehaviorName ํ๋กํผํฐ๋, <contex:mbean=export>์ registration ์ ํธ๋ฆฌ๋ทฐํธ๋ฅผ ์ด์ฉํ์ฌ, ์ถฉ๋์ ์ฒ๋ฆฌํ ์ ์๋ค
@Bean
public MBeanExporter mbeanExporter(SpittleController spittleController, MBeanInfoAssembler assembler) {
MBeanExporter exporter = new MBeanExporter();
Map<String, Object> beans = new HashMap<String, Object>(); beans.put("spitter:name=SpittleController", spittleController); exporter.setBeans(beans);
exporter.setAssembler(assembler);
exporter.setRegistrationPolicy(RegistrationPolicy.IGNORE_EXISTING); // ์ถฉ๋์ ๋ฌด์ํ๊ณ , ์ ๋น์ ๋ฑ๋กํ์ง ์์
return exporter;
}
FAIL_ON_EXISTING : ์คํจ (default)
IGNORE_EXISTING : ์ถฉ๋ ๋ฌด์ํ๊ณ , ์ ๋น ๋ฑ๋กํ์ง ์์
REPLACING_EXISTING : ๊ธฐ์กด ๋น์, ์๋ก์ด ๋น์ผ๋ก ๋์ฒด
2. MBean ๋ฆฌ๋ชจํ
์๊ฒฉ JMX์ ํ์ค์ด ํ์ํด์ง๋ฉฐ, JSR-160, ์ฆ JMX ์๊ฒฉ API ๋ช ์ธ๊ฐ ๋ง๋ค์ด์ง. ์ต์ RMI ๋ฐ์ธ๋ฉ์ ํ์๋ก ์๊ตฌํ๋ฉฐ, ์ ํ์ ์ผ๋ก JMX ๋ฉ์์ง ํ๋กํ ์ฝ(JMXMP)์ ์๊ตฌ
2.1 ์๊ฒฉ์ผ๋ก MBean ๋ ธ์ถํ๊ธฐ
MBean์ ์๊ฒฉ ๊ฐ์ฒด๋ก ์ด์ฉํ๊ธฐ ์ํด, ์คํ๋ง์ ConnectionServerFactoryBean ๊ตฌ์ฑ
@Bean
public ConnectorServerFactoryBean connectorServerFactoryBean() {
return new ConnectorServerFactoryBean();
}
ํด๋น ํฉํ ๋ฆฌ๋น์ JMXConnectorServer๋ฅผ ์์ฑํ๊ณ ์์ => 9875ํฌํธ -> service:jmx:jmxmp://localhost:9875
* JMX ๊ตฌํ์ฒด์ ๋ฐ๋ผ, RMI, SOAP, Hessian/Burlap, IIO๋ฅผ ํฌํจํ์ฌ, ๋ช ๊ฐ์ง์ ์๊ฒฉ ํ๋กํ ์ฝ ์ต์ ์ด ์กด์ฌ
==> RMI๋ฅผ ์ด์ฉํ์ฌ, MBean์ ์ด์ฉํ๊ธฐ
// serviceURL์ RMI๋ฅผ ์ฌ์ฉ
@Bean
public ConnectorServerFactoryBean connectorServerFactoryBean() {
ConnectorServerFactoryBean csfb = new ConnectorServerFactoryBean();
csfb.setServiceUrl("service:jmx:rmi://localhost/jndi/rmi://localhost:1099/spitter"); // RMI ๋ ์ง์คํธ๋ฆฌ์ ๋ฐ์ธ๋ฉ(1099)
return csfb;
}
// RMI ๋ ์ง์คํธ๋ฆฌ ํฉํ ๋ฆฌ ๋น์ ํตํด, MBean์ด์ฉ
@Bean
public RmiRegistryFactoryBean rmiRegistryFB() {
RmiRegistryFactoryBean rmiRegistryFB = new RmiRegistryFactoryBean();
rmiRegistryFB.setPort(1099);
return rmiRegistryFB;
}
2.2 ์๊ฒฉ MBean์ ์ก์ธ์ค
์๊ฒฉ MBean์๋ฒ์ ์ก์ธ์คํ๋ ค๋ฉด, MBeanServerConnectionFactoryBean์ ์ค์ ํด์ผ ํจ
// ์์์ ๋ง๋ rmi ์๋ฒ์ ์ก์ธ์คํ๋, ํฉํ ๋ฆฌ๋น ์ ์ธ
@Bean
public MBeanServerConnectionFactoryBean connectionFactoryBean() {
MBeanServerConnectionFactoryBean mbscfb = new MBeanServerConnectionFactoryBean();
mbscfb.setServiceUrl("service:jmx:rmi://localhost/jndi/rmi://localhost:1099/spitter");
return mbscfb;
}
// ๋ค ๋น๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก, ๋น ํ๋กํผํฐ๋ก ์ฐ๊ฒฐ
@Bean
public JmxClient jmxClient(MBeanServerConnection connection) {
JmxClient jmxClient = new JmxClient();
jmxClient.setMbeanServerConnection(connection);
return jmxClient;
}
* MBeanServerConnection์์๋ ์๊ฒฉ MBean ์๋ฒ๋ฅผ ์ฟผ๋ฆฌํ๋ฉฐ, ํฌํจ๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๋ ๋ช ๊ฐ์ง ๋ฉ์๋๊ฐ ํฌํจ๋จ
// MBean์ ์๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฉ์๋
int mbeanCount = mbeanServerConnection.getMBeanCount
// ์๊ฒฉ์๋ฒ์ ๋ชจ๋ MBean์ ์ด๋ฆ์ ์ฟผ๋ฆฌํจ
java.util.Set mbeanNames = mbeanServerConnection.queryNames(null, null);
// ์ด ์ธ์๋, MBean ์ ํธ๋ฆฌ๋ทฐํธ์ ์ก์ธ์ค๋ ๊ฐ๋ฅ(getAttribute)
String cronExpression = mbeanServerConnection.getAttribute(new ObjectName("spitter:name=SpittleController"), "spittlesPerPage");
// ๋ง์ฐฌ๊ฐ์ง๋ก ๊ฐ ๋ณ๊ฒฝ๋ ๊ฐ๋ฅํ๋ค(setAttribute)
mbeanServerConnection.setAttribute(new ObjectName("spitter:name=SpittleController"), new Attribute("spittlesPerPage", 10));
// ์คํผ๋ ์ด์
์ ํธ์ถํ ์ ์์(invoke), setSpittlesPerPage ์ฌ์ฉ
mbeanServerConnection.invoke(
new ObjectName("spitter:name=SpittleController"),
"setSpittlesPerPage",
new Object[] { 100 },
new String[] {"int"}
);
=> invoke() ๋ฉ์๋์ ๊ฒฝ์ฐ, ์ผ์ผ์ด ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฌํด์ค์ผ ํ๋๋ฐ, ์ด๋ฌํ ์ ์ ์ผ๋ฐ์ ์ธ ๋ฉ์๋ ํธ์ถ๋งํผ ์ง๊ด์ ์ด์ง ์๋ค
=> ํ๋ก์๋ฅผ ๋ง๋ฌ
2.3 MBean ํ๋ก์ ๋ง๋ค๊ธฐ
MBeanProxyFactoryBean : 15์ฅ์ ๋ฆฌ๋ชจํ ํ๋ก์ ๋น๋ค๊ณผ ๊ฐ์ ์ฑ์ง์ ํ๋ก์ ํฉํ ๋ฆฌ ๋น
// ์์์ ๊ตฌํํ ์ ์ด ์๋, SpittleControllerManagedOperations ์ธํฐํ์ด์ค๋ฅผ ํ๋ก์๋ก ์ด์ฉ
@Bean
public MBeanProxyFactoryBean remoteSpittleControllerMBean(MBeanServerConnection mbeanServerClient) {
MBeanProxyFactoryBean proxy = new MBeanProxyFactoryBean();
proxy.setObjectName("");
proxy.setServer(mbeanServerClient);
proxy.setProxyInterface(SpittleControllerManagedOperations.class);
return proxy;
}

3. ํต์ง์ฒ๋ฆฌ
์ดํ๋ฆฌ์ผ์ด์ ์ ์ค์ํ ์ด๋ฒคํธ๋ฅผ ํ์ ํ, ํต์ง๋ฅผ ํ๊ธฐ์ํด ์คํ๋ง์ NotificicationPublisherAware ์ธํฐํ์ด์ค๋ก ํต์ง ์ ์ก์ ํ ์ ์์
=> ์ผ๋จ, ์ ์กํ๊ณ ์ ํ๋ MBean์ ๋ชจ๋ ์ด ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผํจ

@Component
@ManagedResource("spitter:name=SpitterNotifier")
@ManagedNotification(notificationTypes="SpittleNotifier.OneMillionSpittles", name="TODO")
public class SpittleNotifierImpl implements NotificationPublisherAware, SpittleNotifier { // ํผ๋ธ๋ฆฌ์
์ด์จ์ด ๊ตฌํ
private NotificationPublisher notificationPublisher;
public void setNotificationPublisher(NotificationPublisher notificationPublisher) { // ํผ๋ธ๋ฆฌ์
์ฃผ์
this.notificationPublisher = notificationPublisher;
}
public void millionthSpittlePosted() { // ํต์ง ์ ์ก
notificationPublisher.sendNotification(new Notification("SpittleNotifier.OneMillionSpittles", this, 0));
}
}
* ์๊ตฌ๊ฐ ๋ง์ ์ธํฐํ์ด์ค๊ฐ ์๋ setNotificationPublisher๋ง ๊ตฌํํ๋ฉด ๋จ =>> ์๋์ฃผ์ ๋๋ NotificationPublisher๋ฅผ ์ด์ฉ
* setNotification() ๋ฉ์๋๊ฐ ํธ์ถ ๋๋ฉด, ํต์ง๊ฐ ์ด๋๋ก ๊ฐ ๊ฐ๊ณ ์๋ค => ๋ฆฌ์ค๋๊ฐ ๋ฐ์ํ๋๋ก ์ค์
3.1 ํต์ง ๋ฃ๊ธฐ
ํต์ง๋ฅผ ๋ฐ๋ํ์ค ๋ฐฉ์์ NotificationListener์ ๊ตฌํ
public class PagingNotificationListener implements NotificationListener {
public void handleNotification(Notification notification, Object handback) {
~~~~~
}
}
* PaginNotificationListener๋ ์ ํ์ ์ธ JMX ํต์ง ๋ฆฌ์ค๋,. ํต์ง๋ฅผ ๋ฐ์ผ๋ฉด ํต์ง์ ๋ฐ์ํ๊ธฐ ์ํด handleNotification() ๋ฉ์๋๊ฐ ํธ์ถ๋๋ค.
* ์ค์ ๊ตฌํ์ ์ฑ
์ ์์.. ์ฑ
๋ ์ด์ ๊ท์ฐฎ์๋ฏ
* ๋ง์ง๋ง์ผ๋ก MBeanExporter๋ก ํด๋น ๋ฆฌ์ค๋๋ฅผ ๋ฑ๋กํ๋ค
@Bean
public MBeanExporter mbeanExporter() {
MBeanExporter exporter = new MBeanExporter();
Map<?, NotificationListener> mappings =
new HashMap<?, NotificationListener>();
mappings.put("Spitter:name=PagingNotificationListener", new PagingNotificationListener());
exporter.setNotificationListenerMappings(mappings);
return exporter;
}
* notificationListenerMappings ํ๋กํผํฐ๋ ํต์ง ๋ฆฌ์ค๋๋ฅผ ํด๋น MBean์ ๋งคํ
Last updated