The thing about CLOS accessors is that they define methods; they are not just for the sake of having the (setf (foo obj) val) shorthand.
By saying that you have an accessor x, you're writing a method called x. Actually two: x and (setf x).
You can write auxiliary methods for these: with :around, :before and :after methods you can intercept the accessor calls to do "reactive" kinds of things.
I think the problem with Java's approach wasn't just in allowing primitive slot access, it was in making that access be simpler and use less boilerplate than accessor access, so people are tempted to use it where it isn't really what they specifically want, and accessors feel like extra work. I think that most of the time when people complain about getters and setters, their main issue is just the extra syntax they require in languages like Java.
In contrast, Lisp makes using accessors the path of least resistance, so if someone does use primitive slot access, they probably consciously really wanted that. In a class definition like:
The :ACCESSSOR option lets you write (x instance) and (setf (x instance) new-value); with or without it you can write (slot-value instance 'x) and (setf (slot-value instance 'x) new-value) for primitive slot access. It's really just a shorthand for defining methods like: But just by providing that little shortcut (and by not having a shortercut for primitive access) it's enough to make getters and setters the default in a way that people rarely complain about.