Is there a naming convention for @ComponentScan basePackageClasses? [closed]
Asked Answered
R

1

15

Spring's @ComponentScan offers a type-safe basePackageClasses attribute - seems a good thing to use especially as it isn't uncommon for packages to be renamed on the project I'm working on. The documentation says:

Consider creating a special no-op marker class or interface in each package that serves no purpose other than being referenced by this attribute.

... but offers no further guidance on the name of such a class. Am wondering if there are any conventions around this. package-info.java already exists in all packages (as enforced by Checkstyle) - would have preferred to reuse this but sadly Java doesn't allow a class of this name.

(If no such standards exist am thinking perhaps PackageInfo, BasePackage, PackageMarker or similar but would prefer to follow convention if there is one.)

Relucent answered 2/12, 2014 at 16:43 Comment(6)
I feel this is kind of opinion based. What I typically do, for example, is store my @Controller types in one package, so I'll name the corresponding class or interface Controllers in Controllers.java.Mella
Agree it may involve opinion but was hoping someone might be able to point me towards evidence of a standard or widely used approach.Relucent
Does basePackageClasses take just the class name, or the fully qualified one? in the latter case, it isn't much more useful than basePackagesGrindery
It is useful because it is type safe - a class is specified rather than a String so if the package name were to change it wouldn't matter.Relucent
This does appear to be primarily opinion, though you could rephrase (perhaps asking for best practices). I don't think there are any standards, though.Socialize
OK, thought the question already gave that gist but have slightly reworded and bracketed the last sentence to make this clearer.Relucent
R
16

No answers yet and had to make a decision so here it is:

Marker class:

package com.companyname.appname.projectname.package1name;

/**
 * Empty marker class used to identify this package when using type-safe basePackageClasses in Spring @ComponentScan.
 */
public class PackageMarker {
    // Empty marker class
}

Usage:

@ComponentScan(basePackageClasses = {
    com.companyname.appname.projectname.package1name.PackageMarker.class,
    com.companyname.appname.projectname.package2name.PackageMarker.class,
    /* ...etc... */
})

PackageMarker naming justification:

  1. Seems sensible for all such classes to have the same name so they can be easily identified.
  2. Seems sensible for it to start with "Package" (in the same way as package-info.java).
  3. Seems sensible for it to end with "Marker" since the documentation refers to a "marker class".
  4. Opted not to include the word "Base" so it isn't confused with base classes.
  5. Opted not to include the word "Info" as it doesn't contain any info like package-info.java does.
  6. Opted not to include any other words (e.g. "NoOp") to keep it snappy and flexible for other possible uses.

Would still be interested if anyone can give examples of marker classes used in a more trail-blazing context...

Relucent answered 3/12, 2014 at 9:14 Comment(5)
One drawback of this approach is that the usage is very verbose.Kovacev
It's just reflecting the package structure, which can be as terse or verbose as needed to guarantee uniqueness.Relucent
Yes, but you can also give the marker interface a name unique to your project and then the annotation can look like @ComponentScan(basePackageClasses = {TwitterClient.class, EvernoteClient.class})Kovacev
Each to their own but not sure I'd adopt this strategy. The marker class identifies the whole package and this would allow the name to deviate from the package name. There could be issues with name uniqueness later down the line as the number of marker classes grows.Relucent
I would also prevent instantiation of the PackageMarker class by making it final and its constructor private: public final class PackageMarker { private PackageMarker() { throw new AssertionError("Don't instantiate " + PackageMarker.class); } }Humiliating

© 2022 - 2024 — McMap. All rights reserved.