本架构针对业务逻辑处理的大部分功能都是基于java的动态代理进行实现,所以在进行日常代码编写的时候希望尽可能多的使用接口来封装动作
在实际运行当中只要是需要事物管理,缓存管理,切面注入,数据校验等相关功能,或者为主体业务流的一个环节,都需要进行注册代理
按照三层架构思想,个人推荐把业务逻辑层与持久化数据处理层都进行对象注册代理
实现层面每一个需要注册代理的对象都必须对其功能函数声明相应的接口,实际调用也应使用接口调用
每一个已注册代理过的对象,在框架运行中都只实例化一次,在每一个线程中都使用的是同一份代理对象。
所以需要注册代理的对象都是线程不安全的,如果要在对象内声明非代理属性,请仔细斟酌使用。
在任何一个已经代理过的对象中,为其属性标注@Bean注解都能达到注册代理效果
@Bean(thisClass=UserDaoImpl.class)
UserDao userDao;
如上所示UserDaoImpl为UserDao接口的实现类,框架在运行中监测到有@Bean注解都会抽取其中的thisClass属性并为当前属性赋值
被赋值的对象必须为设定属性实现过的接口,否则运行时该对象为null。
也可以使用如下方式标注该属性
@Bean("userService")
UserDao userDao;
但必须保证调用过如下函数进行字符串替换操作
BeanManager.registrationCode(
"userService", UserDaoImpl.class);
或者使用配置工具里面的 框架配置-对象初始化配置 为以上实现类配置一条类型为Class的配置项
也可以在实现类处标注@Bean注解。
@Bean("userService")
public class UserServiceImpl implements UserService {
再调用如下函数
BeanManager.registrationCode(
"com.test.service");
就可以对包路径下的全部实现类进行字符串替换操作
总之凡是需要代理的属性只要打上@Bean注解那么就不用担心该属性的初始化问题,直接调用即可
但如果注册过的代理对象用自身作为属性并在同一个函数内调用该属性的同一个函数,那么就会造成死循环。
示例如下
public class UserServiceImpl implements UserService {
@Bean(thisClass=UserServiceImpl.class)
UserService userService;
@Override
public boolean login(String name) throws SQLException {
return userService.login(name);
}
请在注册代理对象互相调用时避免以上情况
直接注册代理一般用于不打算把注册代理对象作为属性使用的场景,比如用main函数单独运行某一个注册代理对象的时候
public static void main(String[] args) throws SQLException {
UserDao userDao = BeanManager.registrationClass(UserDaoImpl.
class);
userDao.delUserInfo("text");//测试删除是否有效
UserService userService = BeanManager.registrationClass(UserServiceImpl.
class);
userService.login("text");//测试登陆是否正确
}
这种方式可以在任何一个代码段使用,没有前置条件,运行结果与使用@Bean注解完全一致
但必须保证注册代理对象内部的属性全部标注了@Bean注解,否则属性为null
全局注册代理需要使用配置工具 框架配置-对象初始化配置 配置类型为Package的配置项
配置值为希望进行注册代理实现类的所在包,在实际调用的时候就可以完全不需要任何处理,实际例子如下
先配置了com.test.service,com.test.dao然后实现类如下就可以正常调用
public class UserServiceImpl implements UserService {
UserDao userDao;
@Override
public boolean login(String name) throws SQLException {
return userDao.getUserInfo(name) != null;
}
但切记如果一个接口包含多个实现类,那么会根据属性名寻找名称相识度最高的实现类进行赋值
如果调用的注册代理对象在配置包路径之外,那么该属性将不会赋值。调用时会为null