diff --git a/pom.xml b/pom.xml index 8b2aa2d..84a74aa 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,23 @@ + + + org.aspectj + aspectjweaver + 1.9.7 + + + + cglib + cglib + 3.3.0 + + + org.springframework + spring-core + 6.1.2 + com.google.guava diff --git a/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/AopServiceImpl.java b/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/AopServiceImpl.java new file mode 100644 index 0000000..9ecdeb2 --- /dev/null +++ b/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/AopServiceImpl.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2023 niushuai233 niushuai.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cc.niushuai.demo.designpattern.creatormodel.facade._01; + +import cc.niushuai.demo.designpattern.creatormodel.facade._01.entity.AopUser; + +/** + * aop service implementation + * + * @author niushuai233 + * @date 2024/1/29 17:29 + * @since 0.0.1 + */ +public class AopServiceImpl implements AopUserService { + + static { + users.put("zhangsan", new AopUser(1, "zhangsan", "张三")); + users.put("lisi", new AopUser(2, "lisi", "李四")); + users.put("wanger", new AopUser(3, "wanger", "王二")); + users.put("mazi", new AopUser(4, "mazi", "麻子")); + users.put("fox1", new AopUser(5, "fox1", "狐一")); + } +} diff --git a/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/AopUserService.java b/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/AopUserService.java new file mode 100644 index 0000000..87c2fed --- /dev/null +++ b/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/AopUserService.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2023 niushuai233 niushuai.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cc.niushuai.demo.designpattern.creatormodel.facade._01; + +import cc.niushuai.demo.designpattern.creatormodel.facade._01.entity.AopUser; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.StrUtil; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * aop实现外观模式 + * + * @author niushuai233 + * @date 2024/1/29 11:39 + * @since 0.0.1 + */ +public interface AopUserService { + + Map users = new HashMap(); + + default Set userKeys() { + return users.keySet(); + } + + default AopUser queryUserById(Integer id) { + if (null == id) { + return null; + } + return users.values().stream().filter(item -> id.equals(item.getId())).findFirst().orElse(null); + } + + default AopUser queryUserByName(String username) { + if (StrUtil.isEmpty(username)) { + return null; + } + return users.getOrDefault(username, null); + } + + default AopUser queryUser(Object param) { + if (NumberUtil.isNumber(param.toString())) { + AopUser aopUser = queryUserById((Integer) param); + if (null != aopUser) { + return aopUser; + } + } + + return queryUserByName((String) param); + } + + default AopUser aopQueryUser(Object param) { + + return null; + } +} diff --git a/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/HelloAop.java b/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/HelloAop.java new file mode 100644 index 0000000..79e7cb5 --- /dev/null +++ b/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/HelloAop.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 niushuai233 niushuai.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cc.niushuai.demo.designpattern.creatormodel.facade._01; + +import cn.hutool.aop.aspects.SimpleAspect; + +import java.lang.reflect.Method; + +/** + * hello aop + * + * @author niushuai233 + * @date 2024/1/29 17:16 + * @since 0.0.1 + */ +public class HelloAop extends SimpleAspect { + + @Override + public boolean before(Object target, Method method, Object[] args) { + return super.before(target, method, args); + } + + @Override + public boolean after(Object target, Method method, Object[] args, Object returnVal) { + return super.after(target, method, args, returnVal); + } + + @Override + public boolean afterException(Object target, Method method, Object[] args, Throwable e) { + return super.afterException(target, method, args, e); + } +} diff --git a/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/entity/AopUser.java b/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/entity/AopUser.java new file mode 100644 index 0000000..1159df1 --- /dev/null +++ b/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/entity/AopUser.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 niushuai233 niushuai.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cc.niushuai.demo.designpattern.creatormodel.facade._01.entity; + +import lombok.Data; + +/** + * aop user entity + * + * @author niushuai233 + * @date 2024/1/29 16:56 + * @since 0.0.1 + */ +@Data +public class AopUser { + + private Integer id; + private String username; + private String realName; + + public AopUser() { + } + + public AopUser(Integer id, String username, String realName) { + this.id = id; + this.username = username; + this.realName = realName; + } +} diff --git a/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/package-info.java b/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/package-info.java new file mode 100644 index 0000000..5a9bc24 --- /dev/null +++ b/src/main/java/cc/niushuai/demo/designpattern/creatormodel/facade/package-info.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2023 niushuai233 niushuai.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * 外观模式 + * + * @author niushuai233 + * @date 2024/1/29 11:40 + * @since 0.0.1 + */ +package cc.niushuai.demo.designpattern.creatormodel.facade; \ No newline at end of file diff --git a/src/test/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/AopUserTest.java b/src/test/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/AopUserTest.java new file mode 100644 index 0000000..797ce1c --- /dev/null +++ b/src/test/java/cc/niushuai/demo/designpattern/creatormodel/facade/_01/AopUserTest.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2023 niushuai233 niushuai.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cc.niushuai.demo.designpattern.creatormodel.facade._01; + +import cn.hutool.aop.ProxyUtil; +import cn.hutool.aop.aspects.TimeIntervalAspect; +import cn.hutool.aop.interceptor.CglibInterceptor; +import cn.hutool.aop.interceptor.JdkInterceptor; +import net.sf.cglib.proxy.Enhancer; +import org.junit.jupiter.api.Test; +import org.springframework.cglib.proxy.MethodInterceptor; +import org.springframework.cglib.proxy.MethodProxy; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * aop user test + * + * @author niushuai233 + * @date 2024/1/29 17:18 + * @since 0.0.1 + */ +public class AopUserTest { + + + @Test + public void test1() { + AopUserService service = new AopServiceImpl(); + + System.out.println(service.queryUserById(1)); + System.out.println(service.queryUserByName("fox1")); + System.out.println(); + } + + @Test + public void test2() { + AopUserService service = new AopServiceImpl(); + + System.out.println(service.queryUser(1)); + System.out.println(service.queryUser("fox1")); + System.out.println(); + } + + @Test + public void test3() { + + AopUserService service = new AopServiceImpl(); + + AopUserService proxy = ProxyUtil.newProxyInstance( + service.getClass().getClassLoader(), + new JdkInterceptor(service, new TimeIntervalAspect()), + service.getClass().getInterfaces()); + + System.out.println(proxy.queryUser(1)); + System.out.println(proxy.queryUser("fox1")); + System.out.println(); + } + + /** + * jdk17 cglib 存在问题 无法通过 + * 可使用spring-core中的cglib替代 + * + * @return + * @author niushuai233 + * @date 2024/1/29 17:49 + * @since 0.0.1 + */ + @Test + public void test4() { + + AopServiceImpl service = new AopServiceImpl(); + + Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(service.getClass()); + enhancer.setCallback(new CglibInterceptor(service, new TimeIntervalAspect())); + AopServiceImpl proxy = (AopServiceImpl) enhancer.create(); + + System.out.println(proxy.queryUser(1)); + System.out.println(proxy.queryUser("fox1")); + System.out.println(); + } + + /** + * 解决test4中cglib无法正常运行问题 + * + * @return + * @author niushuai233 + * @date 2024/1/29 18:03 + * @since 0.0.1 + */ + @Test + public void test5() { + + AopServiceImpl service = new AopServiceImpl(); + + org.springframework.cglib.proxy.Enhancer enhancer = new org.springframework.cglib.proxy.Enhancer(); + + enhancer.setSuperclass(service.getClass()); + enhancer.setCallback(new MethodInterceptor() { + @Override + public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { + TimeIntervalAspect aspect = new TimeIntervalAspect(); + final Object target = service; + Object result = null; + // 开始前回调 + if (aspect.before(target, method, args)) { + try { +// result = method.invoke(target, args); + result = proxy.invoke(target, args); + } catch (final Throwable e) { + Throwable throwable = e; + if (throwable instanceof InvocationTargetException) { + throwable = ((InvocationTargetException) throwable).getTargetException(); + } + // 异常回调(只捕获业务代码导致的异常,而非反射导致的异常) + if (aspect.afterException(target, method, args, throwable)) { + throw throwable; + } + } + } + + // 结束执行回调 + if (aspect.after(target, method, args, result)) { + return result; + } + return null; + } + }); + AopServiceImpl proxy = (AopServiceImpl) enhancer.create(); + + System.out.println(proxy.queryUser(1)); + System.out.println(proxy.queryUser("fox1")); + System.out.println(); + } + +}