{"id":24264695,"url":"https://github.com/codesmell/reload-spike","last_synced_at":"2025-03-05T00:26:33.577Z","repository":{"id":271625602,"uuid":"913450078","full_name":"CodeSmell/reload-spike","owner":"CodeSmell","description":"Playing with approaches to finding classes that can be \"reloaded\"","archived":false,"fork":false,"pushed_at":"2025-01-08T21:43:21.000Z","size":6,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-08T22:30:23.053Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CodeSmell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-07T17:51:24.000Z","updated_at":"2025-01-08T21:43:24.000Z","dependencies_parsed_at":"2025-01-08T22:40:30.543Z","dependency_job_id":null,"html_url":"https://github.com/CodeSmell/reload-spike","commit_stats":null,"previous_names":["codesmell/reload-spike"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeSmell%2Freload-spike","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeSmell%2Freload-spike/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeSmell%2Freload-spike/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeSmell%2Freload-spike/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CodeSmell","download_url":"https://codeload.github.com/CodeSmell/reload-spike/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241942795,"owners_count":20046432,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-15T09:48:05.457Z","updated_at":"2025-03-05T00:26:33.546Z","avatar_url":"https://github.com/CodeSmell.png","language":"Java","readme":"# Reloadable Classes Spike\nThis application is built as part of a spike to play with ways to find classes that can be \"reloaded\"\n\nIn this scenario the intent is to have some number of types that can have behavior triggered on \nall instances of that type. Perhaps to reload properties or a cache etc\n\n## Annotation\nSpring made it easy to identify Beans that have an annotation marker at the TYPE level\n\n\n    @Autowired\n    private ApplicationContext springContext;\n\n\tMap\u003cString, Object\u003e map = springContext.getBeansWithAnnotation(ReloadableClass.class);\n     \n\nThat opens up the challenge about what method can be called to perform the reload\n\nThe quickest way to identify a method was with another annotation\n\n\n    protected Method getReloadableMethod(Class\u003c?\u003e clazz) {\n        for (Method method : clazz.getDeclaredMethods()) {\n            if (method.isAnnotationPresent(ReloadableMethod.class)) {\n                return method;\n            }\n        }\n    }\n\nThis method can then be invoked as follows:\n\n\tmethod.invoke(instanceOfBean, null);\n\nBasic pro/con\n- The annotation eliminates the need for a naming pattern (Effective Java item 39)\n- The annotation does not require a specific type to be \"reloadable\" (can be applied to any type)\n- The annotation does not require a specific method to be \"reloadable\" (can be applied to any method)\n- Lack of a type means some types of errors will be harder to catch until run-time\n\n## Interface Marker\nEffective Java item 41 suggests that marker interfaces and thus a specific type may be \nmore desirable than an annotation marker. \n\nSpring also makes that really easy to do.\n\n    @Autowired\n    private ApplicationContext springContext;\n    Map\u003cString, ReloadableMarker\u003e map = springContext.getBeansOfType(ReloadableMarker.class);\n\n\nThat still leaves the challenge identifying which method to call to perform the reload.\nThis can be marked with the annotation and invoked as above.\n\nBasic pro/con\n- The interface marker eliminates the need for a naming pattern (Effective Java item 39)\n- The interface marker means classes of a certain type are targeted (Effective Java item 41)\n- The annotation for the method does not require a specific method to be \"reloadable\" (can be applied to any method)\n- Having a specific type allows some errors to be caught at compile-time\n- This is probably a better approach when calling a method isn't needed but rather the type is passed around\n\n## Functional Interface\nSince we want to identify some small number of classes and call a method to trigger some behavior, \nit is reasonable to consider using an interface with a single method\n\n\t@FunctionalInterface\n\tpublic interface Reloadable {\n    \tvoid reload();\n\t}\n\nWe have already seen how to find the classes of a particular type with Spring.\n\n\n    @Autowired\n    private ApplicationContext springContext;\n    Map\u003cString, Reloadable\u003e map = springContext.getBeansOfType(Reloadable.class);\n\nNow we have a type that has a specific method (similar to Runnable) that we can call\n\n\tmyReloadable.reload();\n\nBasic pro/con\n- The interface eliminates the need for a naming pattern (Effective Java item 39)\n- The interface means classes of a certain type are targeted (Effective Java item 41)\n- The interface method requires a specific name for the method but makes it easier to invoke\n- Having a specific type and method allows some errors to be caught at compile-time\n- If we want to add parameters they will be clearly defined, along with their types, in the interface\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodesmell%2Freload-spike","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodesmell%2Freload-spike","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodesmell%2Freload-spike/lists"}