diff --git a/cglib/pom.xml b/cglib/pom.xml
new file mode 100644
index 0000000000..21309cf514
--- /dev/null
+++ b/cglib/pom.xml
@@ -0,0 +1,47 @@
+
+
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+
+ 4.0.0
+
+ cglib
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+
+ cglib
+ cglib
+ ${cglib.version}
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+ 3.2.4
+ 4.12
+
+
+
+
\ No newline at end of file
diff --git a/cglib/src/main/java/com/baeldung/cglib/mixin/Class1.java b/cglib/src/main/java/com/baeldung/cglib/mixin/Class1.java
new file mode 100644
index 0000000000..fa0cba5b78
--- /dev/null
+++ b/cglib/src/main/java/com/baeldung/cglib/mixin/Class1.java
@@ -0,0 +1,8 @@
+package com.baeldung.cglib.mixin;
+
+public class Class1 implements Interface1 {
+ @Override
+ public String first() {
+ return "first behaviour";
+ }
+}
\ No newline at end of file
diff --git a/cglib/src/main/java/com/baeldung/cglib/mixin/Class2.java b/cglib/src/main/java/com/baeldung/cglib/mixin/Class2.java
new file mode 100644
index 0000000000..0db0620ab8
--- /dev/null
+++ b/cglib/src/main/java/com/baeldung/cglib/mixin/Class2.java
@@ -0,0 +1,8 @@
+package com.baeldung.cglib.mixin;
+
+public class Class2 implements Interface2 {
+ @Override
+ public String second() {
+ return "second behaviour";
+ }
+}
\ No newline at end of file
diff --git a/cglib/src/main/java/com/baeldung/cglib/mixin/Interface1.java b/cglib/src/main/java/com/baeldung/cglib/mixin/Interface1.java
new file mode 100644
index 0000000000..56ad679cad
--- /dev/null
+++ b/cglib/src/main/java/com/baeldung/cglib/mixin/Interface1.java
@@ -0,0 +1,5 @@
+package com.baeldung.cglib.mixin;
+
+public interface Interface1 {
+ String first();
+}
\ No newline at end of file
diff --git a/cglib/src/main/java/com/baeldung/cglib/mixin/Interface2.java b/cglib/src/main/java/com/baeldung/cglib/mixin/Interface2.java
new file mode 100644
index 0000000000..0dfb8737ab
--- /dev/null
+++ b/cglib/src/main/java/com/baeldung/cglib/mixin/Interface2.java
@@ -0,0 +1,5 @@
+package com.baeldung.cglib.mixin;
+
+public interface Interface2 {
+ String second();
+}
\ No newline at end of file
diff --git a/cglib/src/main/java/com/baeldung/cglib/mixin/MixinInterface.java b/cglib/src/main/java/com/baeldung/cglib/mixin/MixinInterface.java
new file mode 100644
index 0000000000..e7ed362a25
--- /dev/null
+++ b/cglib/src/main/java/com/baeldung/cglib/mixin/MixinInterface.java
@@ -0,0 +1,4 @@
+package com.baeldung.cglib.mixin;
+
+public interface MixinInterface extends Interface1, Interface2 {
+}
\ No newline at end of file
diff --git a/cglib/src/main/java/com/baeldung/cglib/proxy/PersonService.java b/cglib/src/main/java/com/baeldung/cglib/proxy/PersonService.java
new file mode 100644
index 0000000000..9085e6c49a
--- /dev/null
+++ b/cglib/src/main/java/com/baeldung/cglib/proxy/PersonService.java
@@ -0,0 +1,11 @@
+package com.baeldung.cglib.proxy;
+
+public class PersonService {
+ public String sayHello(String name) {
+ return "Hello " + name;
+ }
+
+ public Integer lengthOfName(String name) {
+ return name.length();
+ }
+}
\ No newline at end of file
diff --git a/cglib/src/test/java/com/baeldung/cglib/proxy/BeanGeneratorTest.java b/cglib/src/test/java/com/baeldung/cglib/proxy/BeanGeneratorTest.java
new file mode 100644
index 0000000000..1e49536065
--- /dev/null
+++ b/cglib/src/test/java/com/baeldung/cglib/proxy/BeanGeneratorTest.java
@@ -0,0 +1,32 @@
+package com.baeldung.cglib.proxy;
+
+
+import net.sf.cglib.beans.BeanGenerator;
+import org.junit.Test;
+
+import java.lang.reflect.Method;
+
+import static junit.framework.TestCase.assertEquals;
+
+public class BeanGeneratorTest {
+
+ @Test
+ public void givenBeanCreator_whenAddProperty_thenClassShouldHaveFieldValue() throws Exception {
+ //given
+ BeanGenerator beanGenerator = new BeanGenerator();
+
+ //when
+ beanGenerator.addProperty("name", String.class);
+ Object myBean = beanGenerator.create();
+ Method setter = myBean
+ .getClass()
+ .getMethod("setName", String.class);
+ setter.invoke(myBean, "some string value set by a cglib");
+
+ //then
+ Method getter = myBean
+ .getClass()
+ .getMethod("getName");
+ assertEquals("some string value set by a cglib", getter.invoke(myBean));
+ }
+}
diff --git a/cglib/src/test/java/com/baeldung/cglib/proxy/MixinTest.java b/cglib/src/test/java/com/baeldung/cglib/proxy/MixinTest.java
new file mode 100644
index 0000000000..db8453e6c1
--- /dev/null
+++ b/cglib/src/test/java/com/baeldung/cglib/proxy/MixinTest.java
@@ -0,0 +1,24 @@
+package com.baeldung.cglib.proxy;
+
+import com.baeldung.cglib.mixin.*;
+import net.sf.cglib.proxy.Mixin;
+import org.junit.Test;
+
+import static junit.framework.TestCase.assertEquals;
+
+public class MixinTest {
+
+ @Test
+ public void givenTwoClasses_whenMixedIntoOne_thenMixinShouldHaveMethodsFromBothClasses() throws Exception {
+ //when
+ Mixin mixin = Mixin.create(
+ new Class[]{Interface1.class, Interface2.class, MixinInterface.class},
+ new Object[]{new Class1(), new Class2()}
+ );
+ MixinInterface mixinDelegate = (MixinInterface) mixin;
+
+ //then
+ assertEquals("first behaviour", mixinDelegate.first());
+ assertEquals("second behaviour", mixinDelegate.second());
+ }
+}
diff --git a/cglib/src/test/java/com/baeldung/cglib/proxy/ProxyTest.java b/cglib/src/test/java/com/baeldung/cglib/proxy/ProxyTest.java
new file mode 100644
index 0000000000..195c4b903d
--- /dev/null
+++ b/cglib/src/test/java/com/baeldung/cglib/proxy/ProxyTest.java
@@ -0,0 +1,60 @@
+package com.baeldung.cglib.proxy;
+
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.FixedValue;
+import net.sf.cglib.proxy.MethodInterceptor;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ProxyTest {
+ @Test
+ public void givenPersonService_whenSayHello_thenReturnResult() {
+ //given
+ PersonService personService = new PersonService();
+
+ //when
+ String res = personService.sayHello("Tom");
+
+ //then
+ assertEquals(res, "Hello Tom");
+ }
+
+ @Test
+ public void givenEnhancerProxy_whenExtendPersonService_thenInterceptMethod() throws Exception {
+ //given
+ Enhancer enhancer = new Enhancer();
+ enhancer.setSuperclass(PersonService.class);
+ enhancer.setCallback((FixedValue) () -> "Hello Tom!");
+ PersonService proxy = (PersonService) enhancer.create();
+
+ //when
+ String res = proxy.sayHello(null);
+
+ //then
+ assertEquals("Hello Tom!", res);
+ }
+
+ @Test
+ public void givenEnhancer_whenExecuteMethodOnProxy_thenInterceptOnlyStringReturnTypeMethod() throws Exception {
+ //given
+ Enhancer enhancer = new Enhancer();
+ enhancer.setSuperclass(PersonService.class);
+ enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
+ if (method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
+ return "Hello Tom!";
+ } else {
+ return proxy.invokeSuper(obj, args);
+ }
+ });
+
+ //when
+ PersonService proxy = (PersonService) enhancer.create();
+
+ //then
+ assertEquals("Hello Tom!", proxy.sayHello(null));
+ int lengthOfName = proxy.lengthOfName("Mary");
+ assertEquals(4, lengthOfName);
+ }
+
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 924bd96ade..ad60436151 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,6 +28,7 @@
autovalue
cdi
+ cglib
core-java
couchbase-sdk